llvm.org GIT mirror llvm / ce046b9
ARM: fix thumb literal loads decoding This fixes two previous issues: - Negative offsets were not correctly disassembled - The decoded opcodes were not the right one git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184180 91177308-0d34-0410-b5e6-96231b3b80d8 Amaury de la Vieuville 7 years ago
4 changed file(s) with 295 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
958958 let Inst{19-16} = addr{16-13}; // Rn
959959 let Inst{15-12} = Rt;
960960 let Inst{11-0} = addr{11-0}; // imm
961
962 let DecoderMethod = "DecodeT2LoadImm12";
961963 }
962964 def i8 : T2Ii8 <(outs target:$Rt), (ins t2addrmode_negimm8:$addr), iii,
963965 opc, "\t$Rt, $addr",
978980 let Inst{9} = addr{8}; // U
979981 let Inst{8} = 0; // The W bit.
980982 let Inst{7-0} = addr{7-0}; // imm
983
984 let DecoderMethod = "DecodeT2LoadImm8";
981985 }
982986 def s : T2Iso <(outs target:$Rt), (ins t2addrmode_so_reg:$addr), iis,
983987 opc, ".w\t$Rt, $addr",
10181022 bits<12> addr;
10191023 let Inst{15-12} = Rt{3-0};
10201024 let Inst{11-0} = addr{11-0};
1025
1026 let DecoderMethod = "DecodeT2LoadLabel";
10211027 }
10221028 }
10231029
12271233
12281234 // Loads with zero extension
12291235 defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1230 rGPR, UnOpFrag<(zextloadi16 node:$Src)>>;
1236 GPR, UnOpFrag<(zextloadi16 node:$Src)>>;
12311237 defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1232 rGPR, UnOpFrag<(zextloadi8 node:$Src)>>;
1238 GPR, UnOpFrag<(zextloadi8 node:$Src)>>;
12331239
12341240 // Loads with sign extension
12351241 defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1236 rGPR, UnOpFrag<(sextloadi16 node:$Src)>>;
1242 GPR, UnOpFrag<(sextloadi16 node:$Src)>>;
12371243 defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1238 rGPR, UnOpFrag<(sextloadi8 node:$Src)>>;
1244 GPR, UnOpFrag<(sextloadi8 node:$Src)>>;
12391245
12401246 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
12411247 // Load doubleword
13721378 let Inst{11} = 1;
13731379 let Inst{10-8} = 0b110; // PUW.
13741380 let Inst{7-0} = addr{7-0};
1381
1382 let DecoderMethod = "DecodeT2LoadT";
13751383 }
13761384
13771385 def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
346346 uint64_t Address, const void *Decoder);
347347 static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
348348 uint64_t Address, const void *Decoder);
349 static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
350 uint64_t Address, const void* Decoder);
351 static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
352 uint64_t Address, const void* Decoder);
353 static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
354 uint64_t Address, const void* Decoder);
355 static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
356 uint64_t Address, const void* Decoder);
349357 static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
350358 uint64_t Address, const void *Decoder);
351359 static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
31873195 uint64_t Address, const void *Decoder) {
31883196 DecodeStatus S = MCDisassembler::Success;
31893197
3190 switch (Inst.getOpcode()) {
3191 case ARM::t2PLDs:
3192 case ARM::t2PLDWs:
3193 case ARM::t2PLIs:
3194 break;
3195 default: {
3196 unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3197 if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3198 return MCDisassembler::Fail;
3199 }
3200 }
3201
3198 unsigned Rt = fieldFromInstruction(Insn, 12, 4);
32023199 unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3200
32033201 if (Rn == 0xF) {
32043202 switch (Inst.getOpcode()) {
32053203 case ARM::t2LDRBs:
32143212 case ARM::t2LDRSBs:
32153213 Inst.setOpcode(ARM::t2LDRSBpci);
32163214 break;
3217 case ARM::t2PLDs:
3215 case ARM::t2LDRs:
3216 Inst.setOpcode(ARM::t2LDRpci);
3217 break;
3218 case ARM::t2PLDs: {
32183219 Inst.setOpcode(ARM::t2PLDi12);
32193220 Inst.addOperand(MCOperand::CreateReg(ARM::PC));
3220 break;
3221 int imm = fieldFromInstruction(Insn, 0, 12);
3222 if (!fieldFromInstruction(Insn, 23, 1)) imm *= -1;
3223 Inst.addOperand(MCOperand::CreateImm(imm));
3224 return S;
3225 }
32213226 default:
32223227 return MCDisassembler::Fail;
32233228 }
32243229
3225 int imm = fieldFromInstruction(Insn, 0, 12);
3226 if (!fieldFromInstruction(Insn, 23, 1)) imm *= -1;
3227 Inst.addOperand(MCOperand::CreateImm(imm));
3228
3229 return S;
3230 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3231 }
3232
3233 switch (Inst.getOpcode()) {
3234 case ARM::t2PLDs:
3235 case ARM::t2PLDWs:
3236 case ARM::t2PLIs:
3237 break;
3238 default:
3239 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3240 return MCDisassembler::Fail;
32303241 }
32313242
32323243 unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
32343245 addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
32353246 if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
32363247 return MCDisassembler::Fail;
3248
3249 return S;
3250 }
3251
3252 static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
3253 uint64_t Address, const void* Decoder) {
3254 DecodeStatus S = MCDisassembler::Success;
3255
3256 unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3257 unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3258 unsigned U = fieldFromInstruction(Insn, 9, 1);
3259 unsigned imm = fieldFromInstruction(Insn, 0, 8);
3260 imm |= (U << 8);
3261 imm |= (Rn << 9);
3262
3263 if (Rn == 15) {
3264 switch (Inst.getOpcode()) {
3265 case ARM::t2LDRi8:
3266 Inst.setOpcode(ARM::t2LDRpci);
3267 break;
3268 case ARM::t2LDRBi8:
3269 Inst.setOpcode(ARM::t2LDRBpci);
3270 break;
3271 case ARM::t2LDRSBi8:
3272 Inst.setOpcode(ARM::t2LDRSBpci);
3273 break;
3274 case ARM::t2LDRHi8:
3275 Inst.setOpcode(ARM::t2LDRHpci);
3276 break;
3277 case ARM::t2LDRSHi8:
3278 Inst.setOpcode(ARM::t2LDRSHpci);
3279 break;
3280 default:
3281 return MCDisassembler::Fail;
3282 }
3283 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3284 }
3285
3286 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3287 return MCDisassembler::Fail;
3288 if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3289 return MCDisassembler::Fail;
3290 return S;
3291 }
3292
3293 static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
3294 uint64_t Address, const void* Decoder) {
3295 DecodeStatus S = MCDisassembler::Success;
3296
3297 unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3298 unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3299 unsigned imm = fieldFromInstruction(Insn, 0, 12);
3300 imm |= (Rn << 13);
3301
3302 if (Rn == 15) {
3303 switch (Inst.getOpcode()) {
3304 case ARM::t2LDRi12:
3305 Inst.setOpcode(ARM::t2LDRpci);
3306 break;
3307 case ARM::t2LDRHi12:
3308 Inst.setOpcode(ARM::t2LDRHpci);
3309 break;
3310 case ARM::t2LDRSHi12:
3311 Inst.setOpcode(ARM::t2LDRSHpci);
3312 break;
3313 case ARM::t2LDRBi12:
3314 Inst.setOpcode(ARM::t2LDRBpci);
3315 break;
3316 case ARM::t2LDRSBi12:
3317 Inst.setOpcode(ARM::t2LDRSBpci);
3318 break;
3319 default:
3320 return MCDisassembler::Fail;
3321 }
3322 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3323 }
3324
3325 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3326 return MCDisassembler::Fail;
3327 if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
3328 return MCDisassembler::Fail;
3329 return S;
3330 }
3331
3332 static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
3333 uint64_t Address, const void* Decoder) {
3334 DecodeStatus S = MCDisassembler::Success;
3335
3336 unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3337 unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3338 unsigned imm = fieldFromInstruction(Insn, 0, 8);
3339 imm |= (Rn << 9);
3340
3341 if (Rn == 15) {
3342 switch (Inst.getOpcode()) {
3343 case ARM::t2LDRT:
3344 Inst.setOpcode(ARM::t2LDRpci);
3345 break;
3346 case ARM::t2LDRBT:
3347 Inst.setOpcode(ARM::t2LDRBpci);
3348 break;
3349 case ARM::t2LDRHT:
3350 Inst.setOpcode(ARM::t2LDRHpci);
3351 break;
3352 case ARM::t2LDRSBT:
3353 Inst.setOpcode(ARM::t2LDRSBpci);
3354 break;
3355 case ARM::t2LDRSHT:
3356 Inst.setOpcode(ARM::t2LDRSHpci);
3357 break;
3358 default:
3359 return MCDisassembler::Fail;
3360 }
3361 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3362 }
3363
3364 if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3365 return MCDisassembler::Fail;
3366 if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3367 return MCDisassembler::Fail;
3368 return S;
3369 }
3370
3371 static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
3372 uint64_t Address, const void* Decoder) {
3373 DecodeStatus S = MCDisassembler::Success;
3374
3375 unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3376 unsigned U = fieldFromInstruction(Insn, 23, 1);
3377 int imm = fieldFromInstruction(Insn, 0, 12);
3378
3379 // FIXME: detect and decode PLD properly
3380 if (Inst.getOpcode() == ARM::t2LDRBpci && Rt == 15) {
3381 Inst.setOpcode(ARM::t2PLDi12);
3382 Inst.addOperand(MCOperand::CreateReg(ARM::PC));
3383 } else {
3384 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3385 return MCDisassembler::Fail;
3386 }
3387
3388 if (!U) {
3389 // Special case for #-0.
3390 if (imm == 0)
3391 imm = INT32_MIN;
3392 else
3393 imm = -imm;
3394 }
3395 Inst.addOperand(MCOperand::CreateImm(imm));
32373396
32383397 return S;
32393398 }
33513510 addr |= fieldFromInstruction(Insn, 9, 1) << 8;
33523511 addr |= Rn << 9;
33533512 unsigned load = fieldFromInstruction(Insn, 20, 1);
3513
3514 if (Rn == 15) {
3515 switch (Inst.getOpcode()) {
3516 case ARM::t2LDR_PRE:
3517 case ARM::t2LDR_POST:
3518 Inst.setOpcode(ARM::t2LDRpci);
3519 break;
3520 case ARM::t2LDRB_PRE:
3521 case ARM::t2LDRB_POST:
3522 Inst.setOpcode(ARM::t2LDRBpci);
3523 break;
3524 case ARM::t2LDRH_PRE:
3525 case ARM::t2LDRH_POST:
3526 Inst.setOpcode(ARM::t2LDRHpci);
3527 break;
3528 case ARM::t2LDRSB_PRE:
3529 case ARM::t2LDRSB_POST:
3530 Inst.setOpcode(ARM::t2LDRSBpci);
3531 break;
3532 case ARM::t2LDRSH_PRE:
3533 case ARM::t2LDRSH_POST:
3534 Inst.setOpcode(ARM::t2LDRSHpci);
3535 break;
3536 default:
3537 return MCDisassembler::Fail;
3538 }
3539 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3540 }
33543541
33553542 if (!load) {
33563543 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
314314 void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
315315 raw_ostream &O) {
316316 const MCOperand &MO1 = MI->getOperand(OpNum);
317 if (MO1.isExpr())
317 if (MO1.isExpr()) {
318318 O << *MO1.getExpr();
319 else if (MO1.isImm()) {
320 O << markup("
321 << markup("
322 << markup(">]>", "]");
323 }
324 else
325 llvm_unreachable("Unknown LDR label operand?");
319 return;
320 }
321
322 O << markup("
323
324 int32_t OffImm = (int32_t)MO1.getImm();
325 bool isSub = OffImm < 0;
326
327 // Special value for #-0. All others are normal.
328 if (OffImm == INT32_MIN)
329 OffImm = 0;
330 if (isSub) {
331 O << markup("
332 << "#-" << formatImm(-OffImm)
333 << markup(">");
334 } else {
335 O << markup("
336 << "#" << formatImm(OffImm)
337 << markup(">");
338 }
339 O << "]" << markup(">");
326340 }
327341
328342 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
552552
553553
554554 #------------------------------------------------------------------------------
555 # LDR(literal)
556 #------------------------------------------------------------------------------
557 # CHECK: ldr.w r4, [pc, #-0]
558 # CHECK: ldr.w r2, [pc, #-40]
559 # CHECK: ldr.w r1, [pc, #1024]
560 0x5f 0xf8 0x00 0x40
561 0x5f 0xf8 0x28 0x20
562 0xdf 0xf8 0x00 0x14
563
564
565 #------------------------------------------------------------------------------
555566 # LDR(register)
556567 #------------------------------------------------------------------------------
557568 # CHECK: ldr.w r1, [r8, r1]
630641
631642
632643 #------------------------------------------------------------------------------
644 # LDRB(literal)
645 #------------------------------------------------------------------------------
646 # CHECK: ldrb.w r6, [pc, #-0]
647 # CHECK: ldrb.w r10, [pc, #227]
648 # CHECK: ldrb.w r5, [pc, #0]
649 0x1f 0xf8 0x00 0x60
650 0x9f 0xf8 0xe3 0xa0
651 0x9f 0xf8 0x00 0x50
652
653
654 #------------------------------------------------------------------------------
633655 # LDRBT
634656 #------------------------------------------------------------------------------
635657 # CHECK: ldrbt r1, [r2]
698720 # CHECK: ldrh.w r5, [r6, #33]
699721 # CHECK: ldrh.w r5, [r6, #257]
700722 # CHECK: ldrh.w lr, [r7, #257]
701 # CHECK: ldrh.w r0, [pc, #-21]
702723
703724 0x35 0xf8 0x04 0x5c
704725 0x35 0x8c
705726 0xb6 0xf8 0x21 0x50
706727 0xb6 0xf8 0x01 0x51
707728 0xb7 0xf8 0x01 0xe1
708 0x3f 0xf8 0x15 0x00
709729
710730
711731 #------------------------------------------------------------------------------
739759
740760
741761 #------------------------------------------------------------------------------
762 # LDRH(literal)
763 #------------------------------------------------------------------------------
764 # CHECK: ldrh.w r7, [pc, #-0]
765 # CHECK: ldrh.w r5, [pc, #121]
766 # CHECK: ldrh.w r4, [pc, #0]
767 0x3f 0xf8 0x00 0x70
768 0xbf 0xf8 0x79 0x50
769 0xbf 0xf8 0x00 0x40
770
771
772 #------------------------------------------------------------------------------
742773 # LDRSB(immediate)
743774 #------------------------------------------------------------------------------
744775 # CHECK: ldrsb r5, [r5, #-4]
785816
786817
787818 #------------------------------------------------------------------------------
819 # LDRSB(literal)
820 #------------------------------------------------------------------------------
821 # CHECK: ldrsb.w r0, [pc, #-0]
822 # CHECK: ldrsb.w r12, [pc, #80]
823 # CHECK: ldrsb.w r3, [pc, #0]
824 0x1f 0xf9 0x00 0x00
825 0x9f 0xf9 0x50 0xc0
826 0x9f 0xf9 0x00 0x30
827
828
829 #------------------------------------------------------------------------------
788830 # LDRSBT
789831 #------------------------------------------------------------------------------
790832 # CHECK: ldrsbt r1, [r2]
843885 0x33 0xf9 0xff 0xeb
844886 0x32 0xf9 0x04 0x9b
845887 0x3d 0xf9 0x04 0x39
888
889
890 #------------------------------------------------------------------------------
891 # LDRSH(literal)
892 #------------------------------------------------------------------------------
893 # CHECK: ldrsh.w r0, [pc, #-0]
894 # CHECK: ldrsh.w r10, [pc, #-231]
895 # CHECK: ldrsh.w r6, [pc, #0]
896 0x3f 0xf9 0x00 0x00
897 0x3f 0xf9 0xe7 0xa0
898 0xbf 0xf9 0x00 0x60
846899
847900
848901 #------------------------------------------------------------------------------