... | ... |
@@ -618,6 +618,27 @@ public: |
618 | 618 |
FMemcpy->setDoesNotThrow(); |
619 | 619 |
FMemcpy->setDoesNotCapture(1, true); |
620 | 620 |
|
621 |
+ args.clear(); |
|
622 |
+ args.push_back(Type::getInt16Ty(Context)); |
|
623 |
+ FunctionType *FuncTy_5 = FunctionType::get(Type::getInt16Ty(Context), args, false); |
|
624 |
+ Function *FBSwap16 = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, |
|
625 |
+ "llvm.bswap.i16", M); |
|
626 |
+ FBSwap16->setDoesNotThrow(); |
|
627 |
+ |
|
628 |
+ args.clear(); |
|
629 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
630 |
+ FunctionType *FuncTy_6 = FunctionType::get(Type::getInt32Ty(Context), args, false); |
|
631 |
+ Function *FBSwap32 = Function::Create(FuncTy_6, GlobalValue::ExternalLinkage, |
|
632 |
+ "llvm.bswap.i32", M); |
|
633 |
+ FBSwap32->setDoesNotThrow(); |
|
634 |
+ |
|
635 |
+ args.clear(); |
|
636 |
+ args.push_back(Type::getInt64Ty(Context)); |
|
637 |
+ FunctionType *FuncTy_7 = FunctionType::get(Type::getInt64Ty(Context), args, false); |
|
638 |
+ Function *FBSwap64 = Function::Create(FuncTy_7, GlobalValue::ExternalLinkage, |
|
639 |
+ "llvm.bswap.i64", M); |
|
640 |
+ FBSwap16->setDoesNotThrow(); |
|
641 |
+ |
|
621 | 642 |
FunctionType* DummyTy = FunctionType::get(Type::getVoidTy(Context), false); |
622 | 643 |
Function *FRealMemset = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
623 | 644 |
"memset", M); |
... | ... |
@@ -633,7 +654,7 @@ public: |
633 | 633 |
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
634 | 634 |
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
635 | 635 |
args.push_back(EE->getTargetData()->getIntPtrType(Context)); |
636 |
- FunctionType* FuncTy_5 = FunctionType::get(Type::getInt32Ty(Context), |
|
636 |
+ FuncTy_5 = FunctionType::get(Type::getInt32Ty(Context), |
|
637 | 637 |
args, false); |
638 | 638 |
Function* FRealMemcmp = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, "memcmp", M); |
639 | 639 |
EE->addGlobalMapping(FRealMemcmp, (void*)(intptr_t)memcmp); |
... | ... |
@@ -1087,6 +1108,31 @@ public: |
1087 | 1087 |
unreachable = true; |
1088 | 1088 |
} |
1089 | 1089 |
break; |
1090 |
+ case OP_BC_BSWAP16: |
|
1091 |
+ { |
|
1092 |
+ CallInst *C = Builder.CreateCall(FBSwap16, convertOperand(func, inst, inst->u.unaryop)); |
|
1093 |
+ C->setTailCall(true); |
|
1094 |
+ C->setDoesNotThrow(true); |
|
1095 |
+ Store(inst->dest, C); |
|
1096 |
+ break; |
|
1097 |
+ } |
|
1098 |
+ case OP_BC_BSWAP32: |
|
1099 |
+ { |
|
1100 |
+ CallInst *C = Builder.CreateCall(FBSwap32, convertOperand(func, inst, inst->u.unaryop)); |
|
1101 |
+ C->setTailCall(true); |
|
1102 |
+ C->setDoesNotThrow(true); |
|
1103 |
+ Store(inst->dest, C); |
|
1104 |
+ break; |
|
1105 |
+ } |
|
1106 |
+ case OP_BC_BSWAP64: |
|
1107 |
+ { |
|
1108 |
+ CallInst *C = Builder.CreateCall(FBSwap64, convertOperand(func, inst, inst->u.unaryop)); |
|
1109 |
+ C->setTailCall(true); |
|
1110 |
+ C->setDoesNotThrow(true); |
|
1111 |
+ Store(inst->dest, C); |
|
1112 |
+ break; |
|
1113 |
+ } |
|
1114 |
+ |
|
1090 | 1115 |
default: |
1091 | 1116 |
errs() << MODULE << "JIT doesn't implement opcode " << |
1092 | 1117 |
inst->opcode << " yet!\n"; |
... | ... |
@@ -80,6 +80,9 @@ enum bc_opcode { |
80 | 80 |
OP_BC_MEMCMP, |
81 | 81 |
OP_BC_ISBIGENDIAN, |
82 | 82 |
OP_BC_ABORT, |
83 |
+ OP_BC_BSWAP16, |
|
84 |
+ OP_BC_BSWAP32, |
|
85 |
+ OP_BC_BSWAP64, |
|
83 | 86 |
OP_BC_INVALID /* last */ |
84 | 87 |
}; |
85 | 88 |
|
... | ... |
@@ -105,8 +108,8 @@ static const unsigned char operand_counts[] = { |
105 | 105 |
3, 3, 3, 3, |
106 | 106 |
/* OP_BC_ISBIGENDIAN */ |
107 | 107 |
0, |
108 |
- /* OP_BC_ABORT */ |
|
109 |
- 0 |
|
108 |
+ /* OP_BC_ABORT, OP_BSWAP* */ |
|
109 |
+ 0, 1, 1, 1 |
|
110 | 110 |
}; |
111 | 111 |
|
112 | 112 |
enum bc_global { |