aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/CppBackend/CPPBackend.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-11-23 21:23:07 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-11-23 21:23:07 -0800
commitfec33965e0ef1ce9f1e81483f758e8807ba63992 (patch)
treea3251561b53da849663858bb0b3030e32a482003 /lib/Target/CppBackend/CPPBackend.cpp
parent56fad62c5e983b81343f3d3335b64f9bafe70eb6 (diff)
handle unaligned stores
Diffstat (limited to 'lib/Target/CppBackend/CPPBackend.cpp')
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp64
1 files changed, 59 insertions, 5 deletions
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 079f792d93..6d5af3ebaa 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -1497,12 +1497,66 @@ std::string CppWriter::generateInstruction(const Instruction *I) {
const Value *P = SI->getPointerOperand();
const Value *V = SI->getValueOperand();
std::string VS = getValueAsStr(V);
- if (V->getType()->isDoubleTy() && SI->getAlignment() == 4) {
- // only 4-byte aligned, copy carefully
- std::string PS = getOpName(P);
- text = "HEAPF64[tempDoublePtr>>3]=" + VS + ";HEAPF32[" + PS + ">>2]=HEAPF32[tempDoublePtr>>2];HEAPF32[" + PS + "+4>>2]=HEAPF32[tempDoublePtr+4>>2];";
- } else {
+ unsigned Bytes = V->getType()->getIntegerBitWidth()/8;
+ unsigned Alignment = SI->getAlignment();
+ if (Bytes <= Alignment) {
text = getPtrUse(P) + " = " + VS + ";";
+ } else {
+ // unaligned in some manner
+ std::string PS = getOpName(P);
+ switch (Bytes) {
+ case 8: {
+ switch (Alignment) {
+ case 4: {
+ text = "HEAPF64[tempDoublePtr>>3]=" + VS + ";HEAP32[" + PS + ">>2]=HEAP32[tempDoublePtr>>2];HEAP32[" + PS + "+4>>2]=HEAP32[tempDoublePtr+4>>2];";
+ break;
+ }
+ default: assert(0 && "bad 8 store");
+ }
+ break;
+ }
+ case 4: {
+ if (V->getType()->isIntegerTy()) {
+ switch (Alignment) {
+ case 2: {
+ text = "HEAP16[" + PS + ">>1]=" + VS + "&65535;" +
+ "HEAP16[" + PS + "+2>>1]=" + VS + ">>2;";
+ break;
+ }
+ case 1: {
+ text = "HEAP8[" + PS + "]=" + VS + "&255;" +
+ "HEAP8[" + PS + "+1]=(" + VS + ">>8)&255;" +
+ "HEAP8[" + PS + "+2]=(" + VS + ">>16)&255;" +
+ "HEAP8[" + PS + "+3]=" + VS + ">>24;";
+ }
+ default: assert(0 && "bad 4i store");
+ }
+ } else { // float
+ text = "HEAPF32[tempDoublePtr>>2]=" + VS + ';';
+ switch (Alignment) {
+ case 2: {
+ text = "HEAP16[" + PS + ">>1]=HEAP16[tempDoublePtr>>1];" +
+ "HEAP16[" + PS + "+2>>1]=HEAP16[tempDoublePtr+2>>1];";
+ break;
+ }
+ case 1: {
+ text = "HEAP8[" + PS + "]=HEAP8[tempDoublePtr];" +
+ "HEAP8[" + PS + "+1]=HEAP8[tempDoublePtr+1];" +
+ "HEAP8[" + PS + "+2]=HEAP8[tempDoublePtr+2];" +
+ "HEAP8[" + PS + "+3]=HEAP8[tempDoublePtr+3];";
+ }
+ default: assert(0 && "bad 4f store");
+ }
+ }
+ break;
+ }
+ case 2: {
+ text = "HEAP8[" + PS + "]=" + VS + "&255;" +
+ "HEAP8[" + PS + "+1]=" + VS + ">>8;";
+ break;
+ }
+ default: assert(0 && "bad store");
+ }
}
break;
}