llvm.org GIT mirror llvm / 2d524b0
Fix issues with the ARM bl and blx thumb instructions and the J1 and J2 bits for the assembler and disassembler. Which were not being set/read correctly for offsets greater than 22 bits in some cases. Changes to lib/Target/ARM/ARMAsmBackend.cpp from Gideon Myles! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156118 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 8 years ago
6 changed file(s) with 128 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
426426 "bl${p}\t$func",
427427 [(ARMtcall tglobaladdr:$func)]>,
428428 Requires<[IsThumb]> {
429 bits<22> func;
430 let Inst{26} = func{21};
429 bits<24> func;
430 let Inst{26} = func{23};
431431 let Inst{25-16} = func{20-11};
432 let Inst{13} = 1;
433 let Inst{11} = 1;
432 let Inst{13} = func{22};
433 let Inst{11} = func{21};
434434 let Inst{10-0} = func{10-0};
435435 }
436436
440440 "blx${p}\t$func",
441441 [(ARMcall tglobaladdr:$func)]>,
442442 Requires<[IsThumb, HasV5T]> {
443 bits<21> func;
443 bits<24> func;
444 let Inst{26} = func{23};
444445 let Inst{25-16} = func{20-11};
445 let Inst{13} = 1;
446 let Inst{11} = 1;
446 let Inst{13} = func{22};
447 let Inst{11} = func{21};
447448 let Inst{10-1} = func{10-1};
448449 let Inst{0} = 0; // func{0} is assumed zero
449450 }
33383338
33393339 static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
33403340 uint64_t Address, const void *Decoder) {
3341 // Val is passed in as S:J1:J2:imm10H:imm10L:’0’
3342 // Note only one trailing zero not two. Also the J1 and J2 values are from
3343 // the encoded instruction. So here change to I1 and I2 values via:
3344 // I1 = NOT(J1 EOR S);
3345 // I2 = NOT(J2 EOR S);
3346 // and build the imm32 with two trailing zeros as documented:
3347 // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:’00’, 32);
3348 unsigned S = (Val >> 23) & 1;
3349 unsigned J1 = (Val >> 22) & 1;
3350 unsigned J2 = (Val >> 21) & 1;
3351 unsigned I1 = !(J1 ^ S);
3352 unsigned I2 = !(J2 ^ S);
3353 unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
3354 int imm32 = SignExtend32<25>(tmp << 1);
3355
33413356 if (!tryAddingSymbolicOperand(Address,
3342 (Address & ~2u) + SignExtend32<22>(Val << 1) + 4,
3357 (Address & ~2u) + imm32 + 4,
33433358 true, 4, Inst, Decoder))
3344 Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
3359 Inst.addOperand(MCOperand::CreateImm(imm32));
33453360 return MCDisassembler::Success;
33463361 }
33473362
34553470
34563471 static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
34573472 uint64_t Address, const void *Decoder){
3458 if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<22>(Val<<1) + 4,
3473 // Val is passed in as S:J1:J2:imm10:imm11
3474 // Note no trailing zero after imm11. Also the J1 and J2 values are from
3475 // the encoded instruction. So here change to I1 and I2 values via:
3476 // I1 = NOT(J1 EOR S);
3477 // I2 = NOT(J2 EOR S);
3478 // and build the imm32 with one trailing zero as documented:
3479 // imm32 = SignExtend(S:I1:I2:imm10:imm11:’0’, 32);
3480 unsigned S = (Val >> 23) & 1;
3481 unsigned J1 = (Val >> 22) & 1;
3482 unsigned J2 = (Val >> 21) & 1;
3483 unsigned I1 = !(J1 ^ S);
3484 unsigned I2 = !(J2 ^ S);
3485 unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
3486 int imm32 = SignExtend32<25>(tmp << 1);
3487
3488 if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
34593489 true, 4, Inst, Decoder))
3460 Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
3490 Inst.addOperand(MCOperand::CreateImm(imm32));
34613491 return MCDisassembler::Success;
34623492 }
34633493
393393 return swapped;
394394 }
395395 case ARM::fixup_arm_thumb_bl: {
396 // The value doesn't encode the low bit (always zero) and is offset by
397 // four. The value is encoded into disjoint bit positions in the destination
398 // opcode. x = unchanged, I = immediate value bit, S = sign extension bit
399 //
400 // BL: xxxxxSIIIIIIIIII xxxxxIIIIIIIIIII
401 //
402 // Note that the halfwords are stored high first, low second; so we need
403 // to transpose the fixup value here to map properly.
404 unsigned isNeg = (int64_t(Value - 4) < 0) ? 1 : 0;
405 uint32_t Binary = 0;
406 Value = 0x3fffff & ((Value - 4) >> 1);
407 Binary = (Value & 0x7ff) << 16; // Low imm11 value.
408 Binary |= (Value & 0x1ffc00) >> 11; // High imm10 value.
409 Binary |= isNeg << 10; // Sign bit.
410 return Binary;
396 // The value doesn't encode the low bit (always zero) and is offset by
397 // four. The 32-bit immediate value is encoded as
398 // imm32 = SignExtend(S:I1:I2:imm10:imm11:0)
399 // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
400 // The value is encoded into disjoint bit positions in the destination
401 // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
402 // J = either J1 or J2 bit
403 //
404 // BL: xxxxxSIIIIIIIIII xxJxJIIIIIIIIIII
405 //
406 // Note that the halfwords are stored high first, low second; so we need
407 // to transpose the fixup value here to map properly.
408 uint32_t offset = (Value - 4) >> 1;
409 uint32_t signBit = (offset & 0x800000) >> 23;
410 uint32_t I1Bit = (offset & 0x400000) >> 22;
411 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
412 uint32_t I2Bit = (offset & 0x200000) >> 21;
413 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
414 uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
415 uint32_t imm11Bits = (offset & 0x000007FF);
416
417 uint32_t Binary = 0;
418 uint32_t firstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
419 uint32_t secondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
420 (uint16_t)imm11Bits);
421 Binary |= secondHalf << 16;
422 Binary |= firstHalf;
423 return Binary;
424
411425 }
412426 case ARM::fixup_arm_thumb_blx: {
413 // The value doesn't encode the low two bits (always zero) and is offset by
414 // four (see fixup_arm_thumb_cp). The value is encoded into disjoint bit
415 // positions in the destination opcode. x = unchanged, I = immediate value
416 // bit, S = sign extension bit, 0 = zero.
417 //
418 // BLX: xxxxxSIIIIIIIIII xxxxxIIIIIIIIII0
419 //
420 // Note that the halfwords are stored high first, low second; so we need
421 // to transpose the fixup value here to map properly.
422 unsigned isNeg = (int64_t(Value-4) < 0) ? 1 : 0;
423 uint32_t Binary = 0;
424 Value = 0xfffff & ((Value - 2) >> 2);
425 Binary = (Value & 0x3ff) << 17; // Low imm10L value.
426 Binary |= (Value & 0xffc00) >> 10; // High imm10H value.
427 Binary |= isNeg << 10; // Sign bit.
428 return Binary;
427 // The value doesn't encode the low two bits (always zero) and is offset by
428 // four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as
429 // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
430 // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
431 // The value is encoded into disjoint bit positions in the destination
432 // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
433 // J = either J1 or J2 bit, 0 = zero.
434 //
435 // BLX: xxxxxSIIIIIIIIII xxJxJIIIIIIIIII0
436 //
437 // Note that the halfwords are stored high first, low second; so we need
438 // to transpose the fixup value here to map properly.
439 uint32_t offset = (Value - 2) >> 2;
440 uint32_t signBit = (offset & 0x400000) >> 22;
441 uint32_t I1Bit = (offset & 0x200000) >> 21;
442 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
443 uint32_t I2Bit = (offset & 0x100000) >> 20;
444 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
445 uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
446 uint32_t imm10LBits = (offset & 0x3FF);
447
448 uint32_t Binary = 0;
449 uint32_t firstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
450 uint32_t secondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
451 ((uint16_t)imm10LBits) << 1);
452 Binary |= secondHalf << 16;
453 Binary |= firstHalf;
454 return Binary;
429455 }
430456 case ARM::fixup_arm_thumb_cp:
431457 // Offset by 4, and don't encode the low two bits. Two bytes of that
168168 bl _bar
169169 blx _baz
170170
171 @ CHECK: bl _bar @ encoding: [A,0xf0'A',A,0xf8'A']
171 @ CHECK: bl _bar @ encoding: [A,0xf0'A',A,0xd0'A']
172172 @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_bl
173 @ CHECK: blx _baz @ encoding: [A,0xf0'A',A,0xe8'A']
173 @ CHECK: blx _baz @ encoding: [A,0xf0'A',A,0xc0'A']
174174 @ fixup A - offset: 0, value: _baz, kind: fixup_arm_thumb_blx
175175
176176
300300
301301 # CHECK: mrs r0, apsr
302302 0xef 0xf3 0x00 0x80
303
304 # rdar://11313994
305 # CHECK: blx #2313244
306 0x34 0xf2 0x0e 0xee
307
308 # rdar://11324693
309 # CHECK: bl #-12303196
310 0x44 0xf4 0x52 0xda
0 @ RUN: llvm-mc -triple=thumbv7-apple-darwin -filetype=obj -o - < %s | macho-dump --dump-section-data | FileCheck %s
1 .thumb
2 .thumb_func t
3 t: nop
4
5 .data
6 .space 4441096 - 4 - 2
7
8 .section __TEXT, __branch, regular, pure_instructions
9 .thumb
10 .thumb_func b
11 b:
12 bl t
13 # CHECK: '_section_data', 'c3f7fcf5'
14 # We are checking that the branch and link instruction which is:
15 # bl #-4441096
16 # has it displacement encoded correctly with respect to the J1 and J2 bits when
17 # the branch is assembled with a label not a displacement.
18 # rdar://10149689