aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/CppBackend/CPPBackend.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-11-23 22:12:17 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-11-23 22:12:17 -0800
commitcf56c980112955f88756a24c3b14428091869e0c (patch)
tree17a58bffd84ad4b0ebc4c2fd995c866eeeedb569 /lib/Target/CppBackend/CPPBackend.cpp
parenta4e92ab00687d2157b3743b71c6d190ecfea7b7a (diff)
handle unaligned loads
Diffstat (limited to 'lib/Target/CppBackend/CPPBackend.cpp')
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp110
1 files changed, 95 insertions, 15 deletions
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 396ce57747..44629f4b16 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -1487,9 +1487,89 @@ std::string CppWriter::generateInstruction(const Instruction *I) {
}
case Instruction::Load: {
const LoadInst *LI = cast<LoadInst>(I);
- const Value *Ptr = LI->getPointerOperand();
- Type *t = cast<PointerType>(Ptr->getType())->getElementType();
- text = getAssign(iName, t) + getPtrLoad(Ptr) + ";";
+ const Value *P = LI->getPointerOperand();
+ unsigned Bytes = LI->getType()->getPrimitiveSizeInBits()/8;
+ unsigned Alignment = LI->getAlignment();
+ std::string Assign = getAssign(iName, LI->getType());
+ if (Bytes <= Alignment || Alignment == 0) {
+ text = Assign + getPtrUse(P);
+ } else {
+ // unaligned in some manner
+ std::string PS = getOpName(P);
+ switch (Bytes) {
+ case 8: {
+ switch (Alignment) {
+ case 4: {
+ text = "HEAP32[tempDoublePtr>>2]=HEAP32[" + PS + ">>2];" +
+ "HEAP32[tempDoublePtr+4>>2]=HEAP32[" + PS + "+4>>2];";
+ break;
+ }
+ case 2: {
+ text = "HEAP16[tempDoublePtr>>1]=HEAP16[" + PS + ">>1];" +
+ "HEAP16[tempDoublePtr+2>>1]=HEAP16[" + PS + "+2>>1];" +
+ "HEAP16[tempDoublePtr+4>>1]=HEAP16[" + PS + "+4>>1];" +
+ "HEAP16[tempDoublePtr+6>>1]=HEAP16[" + PS + "+6>>1];";
+ break;
+ }
+ case 1: {
+ text = "HEAP8[tempDoublePtr]=HEAP8[" + PS + "];" +
+ "HEAP8[tempDoublePtr+1]=HEAP8[" + PS + "+1];" +
+ "HEAP8[tempDoublePtr+2]=HEAP8[" + PS + "+2];" +
+ "HEAP8[tempDoublePtr+3]=HEAP8[" + PS + "+3];" +
+ "HEAP8[tempDoublePtr+4]=HEAP8[" + PS + "+4];" +
+ "HEAP8[tempDoublePtr+5]=HEAP8[" + PS + "+5];" +
+ "HEAP8[tempDoublePtr+6]=HEAP8[" + PS + "+6];" +
+ "HEAP8[tempDoublePtr+7]=HEAP8[" + PS + "+7];";
+ break;
+ }
+ default: assert(0 && "bad 8 store");
+ }
+ text += Assign + "HEAPF64[tempDoublePtr>>3];";
+ break;
+ }
+ case 4: {
+ if (LI->getType()->isIntegerTy()) {
+ switch (Alignment) {
+ case 2: {
+ text = Assign + "HEAP16[" + PS + ">>1]+" +
+ "(HEAP16[" + PS + "+2>>1]<<2);";
+ break;
+ }
+ case 1: {
+ text = Assign + "HEAP8[" + PS + "]+" +
+ "(HEAP8[" + PS + "+1]<<1)+" +
+ "(HEAP8[" + PS + "+2]<<2)+" +
+ "(HEAP8[" + PS + "+3]<<3)";
+ }
+ default: assert(0 && "bad 4i store");
+ }
+ } else { // float
+ switch (Alignment) {
+ case 2: {
+ text = "HEAP16[tempDoublePtr>>1]=HEAP16[" + PS + ">>1];" +
+ "HEAP16[tempDoublePtr+2>>1]=HEAP16[" + PS + "+2>>1];";
+ break;
+ }
+ case 1: {
+ text = "HEAP8[tempDoublePtr]=HEAP8[" + PS + "];" +
+ "HEAP8[tempDoublePtr+1]=HEAP8[" + PS + "+1];" +
+ "HEAP8[tempDoublePtr+2]=HEAP8[" + PS + "+2]=;" +
+ "HEAP8[tempDoublePtr+3]=HEAP8[" + PS + "+3];";
+ }
+ default: assert(0 && "bad 4f store");
+ }
+ text += Assign + "HEAPF32[tempDoublePtr>>2];";
+ }
+ break;
+ }
+ case 2: {
+ text = Assign + "HEAP8[" + PS + "]+" +
+ "(HEAP8[" + PS + "+1]<<1);";
+ break;
+ }
+ default: assert(0 && "bad store");
+ }
+ }
break;
}
case Instruction::Store: {
@@ -1514,21 +1594,21 @@ std::string CppWriter::generateInstruction(const Instruction *I) {
break;
}
case 2: {
- text += "HEAP16[" + PS + ">>1]=HEAP32[tempDoublePtr>>1];" +
- "HEAP16[" + PS + "+2>>1]=HEAP32[tempDoublePtr+2>>1];" +
- "HEAP16[" + PS + "+4>>1]=HEAP32[tempDoublePtr+4>>1];" +
- "HEAP16[" + PS + "+6>>1]=HEAP32[tempDoublePtr+6>>1];";
+ text += "HEAP16[" + PS + ">>1]=HEAP16[tempDoublePtr>>1];" +
+ "HEAP16[" + PS + "+2>>1]=HEAP16[tempDoublePtr+2>>1];" +
+ "HEAP16[" + PS + "+4>>1]=HEAP16[tempDoublePtr+4>>1];" +
+ "HEAP16[" + PS + "+6>>1]=HEAP16[tempDoublePtr+6>>1];";
break;
}
case 1: {
- text += "HEAP8[" + PS + "]=HEAP32[tempDoublePtr];" +
- "HEAP8[" + PS + "+1]=HEAP32[tempDoublePtr+1];" +
- "HEAP8[" + PS + "+2]=HEAP32[tempDoublePtr+2];" +
- "HEAP8[" + PS + "+3]=HEAP32[tempDoublePtr+3];" +
- "HEAP8[" + PS + "+4]=HEAP32[tempDoublePtr+4];" +
- "HEAP8[" + PS + "+5]=HEAP32[tempDoublePtr+5];" +
- "HEAP8[" + PS + "+6]=HEAP32[tempDoublePtr+6];" +
- "HEAP8[" + PS + "+7]=HEAP32[tempDoublePtr+7];";
+ text += "HEAP8[" + PS + "]=HEAP8[tempDoublePtr];" +
+ "HEAP8[" + PS + "+1]=HEAP8[tempDoublePtr+1];" +
+ "HEAP8[" + PS + "+2]=HEAP8[tempDoublePtr+2];" +
+ "HEAP8[" + PS + "+3]=HEAP8[tempDoublePtr+3];" +
+ "HEAP8[" + PS + "+4]=HEAP8[tempDoublePtr+4];" +
+ "HEAP8[" + PS + "+5]=HEAP8[tempDoublePtr+5];" +
+ "HEAP8[" + PS + "+6]=HEAP8[tempDoublePtr+6];" +
+ "HEAP8[" + PS + "+7]=HEAP8[tempDoublePtr+7];";
break;
}
default: assert(0 && "bad 8 store");