| 3392 | } |
| 3393 | |
| 3394 | void BeMCContext::CreateTableSwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx) |
| 3395 | { |
| 3396 | auto& sect = mCOFFObject->mRDataSect; |
| 3397 | |
| 3398 | auto defaultBlock = GetOperand(switchInst->mDefaultBlock); |
| 3399 | |
| 3400 | auto int32Type = mModule->mContext->GetPrimitiveType(BeTypeCode_Int32); |
| 3401 | auto int32PtrType = mModule->mContext->GetPointerTo(int32Type); |
| 3402 | auto nativeType = mModule->mContext->GetPrimitiveType(BeTypeCode_Int64); |
| 3403 | auto nativePtrType = mModule->mContext->GetPointerTo(nativeType); |
| 3404 | |
| 3405 | int64 loVal = switchInst->mCases.front().mValue->mInt64; |
| 3406 | int64 hiVal = switchInst->mCases.back().mValue->mInt64; |
| 3407 | int numVals = switchInst->mCases.size(); |
| 3408 | |
| 3409 | BeMCSymbol* sym = mCOFFObject->mSymbols.Alloc(); |
| 3410 | sym->mType = int32Type; |
| 3411 | sym->mName = StrFormat("@jumpTab%d", mCOFFObject->mCurJumpTableIdx++); |
| 3412 | sym->mIsStatic = true; |
| 3413 | sym->mSymKind = BeMCSymbolKind_External; |
| 3414 | sym->mIdx = (int)mCOFFObject->mSymbols.size() - 1; |
| 3415 | |
| 3416 | mCOFFObject->MarkSectionUsed(sect); |
| 3417 | sym->mSectionNum = sect.mSectionIdx + 1; |
| 3418 | sect.mData.Align(4); |
| 3419 | sect.mAlign = BF_MAX(sect.mAlign, 4); |
| 3420 | sym->mValue = sect.mData.GetSize(); |
| 3421 | |
| 3422 | auto mcValue = GetOperand(switchInst->mValue); |
| 3423 | |
| 3424 | auto beType = GetType(mcValue); |
| 3425 | |
| 3426 | auto mcOfsValue = AllocVirtualReg(nativeType); |
| 3427 | CreateDefineVReg(mcOfsValue); |
| 3428 | if (beType->mSize < 8) |
| 3429 | AllocInst(BeMCInstKind_MovSX, mcOfsValue, mcValue); |
| 3430 | else |
| 3431 | AllocInst(BeMCInstKind_Mov, mcOfsValue, mcValue); |
| 3432 | AllocInst(BeMCInstKind_Sub, mcOfsValue, BeMCOperand::FromImmediate(loVal)); |
| 3433 | AllocInst(BeMCInstKind_CondBr, defaultBlock, BeMCOperand::FromCmpKind(BeCmpKind_SLT)); |
| 3434 | AllocInst(BeMCInstKind_Cmp, mcOfsValue, BeMCOperand::FromImmediate(hiVal - loVal)); |
| 3435 | AllocInst(BeMCInstKind_CondBr, defaultBlock, BeMCOperand::FromCmpKind(BeCmpKind_SGT)); |
| 3436 | |
| 3437 | auto jumpVReg = AllocVirtualReg(nativeType); |
| 3438 | CreateDefineVReg(jumpVReg); |
| 3439 | AllocInst(BeMCInstKind_Mov, jumpVReg, BeMCOperand::FromSymbolAddr(sym->mIdx)); |
| 3440 | |
| 3441 | auto jumpRelVReg = AllocVirtualReg(int32PtrType); |
| 3442 | CreateDefineVReg(jumpRelVReg); |
| 3443 | auto vregInfo = mVRegInfo[jumpRelVReg.mVRegIdx]; |
| 3444 | vregInfo->mIsExpr = true; |
| 3445 | vregInfo->mRelTo = jumpVReg; |
| 3446 | vregInfo->mRelOffset = mcOfsValue; |
| 3447 | vregInfo->mRelOffsetScale = 4; |
| 3448 | jumpRelVReg.mKind = BeMCOperandKind_VRegLoad; |
| 3449 | |
| 3450 | AllocInst(BeMCInstKind_Mov, jumpVReg, jumpRelVReg); |
| 3451 |
nothing calls this directly
no test coverage detected