mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
Add correct encodings for STRD and LDRD, including fixup support. Additionally, update these to unified syntax.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120589 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1920d82f75
commit
9d63d90de5
@ -409,7 +409,7 @@ namespace {
|
||||
case FK_PCRel_2:
|
||||
case FK_PCRel_4:
|
||||
case ARM::fixup_arm_pcrel_12:
|
||||
case ARM::fixup_arm_vfp_pcrel_10:
|
||||
case ARM::fixup_arm_pcrel_10:
|
||||
case ARM::fixup_arm_branch:
|
||||
return true;
|
||||
}
|
||||
@ -1457,7 +1457,7 @@ unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
|
||||
switch ((unsigned)Fixup.getKind()) {
|
||||
default: llvm_unreachable("invalid fixup kind!");
|
||||
case ARM::fixup_arm_pcrel_12:
|
||||
case ARM::fixup_arm_vfp_pcrel_10:
|
||||
case ARM::fixup_arm_pcrel_10:
|
||||
assert(0 && "Unimplemented"); break;
|
||||
case ARM::fixup_arm_branch:
|
||||
return ELF::R_ARM_CALL; break;
|
||||
|
@ -64,7 +64,7 @@ protected:
|
||||
// These values don't encode the low two bits since they're always zero.
|
||||
// Offset by 8 just as above.
|
||||
return (Value - 8) >> 2;
|
||||
case ARM::fixup_arm_vfp_pcrel_10: {
|
||||
case ARM::fixup_arm_pcrel_10: {
|
||||
// Offset by 8 just as above.
|
||||
Value = Value - 8;
|
||||
bool isAdd = true;
|
||||
@ -202,7 +202,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
|
||||
default: llvm_unreachable("Unknown fixup kind!");
|
||||
case FK_Data_4: return 4;
|
||||
case ARM::fixup_arm_pcrel_12: return 3;
|
||||
case ARM::fixup_arm_vfp_pcrel_10: return 3;
|
||||
case ARM::fixup_arm_pcrel_10: return 3;
|
||||
case ARM::fixup_arm_branch: return 3;
|
||||
}
|
||||
}
|
||||
|
@ -181,6 +181,8 @@ namespace {
|
||||
const { return 0; }
|
||||
unsigned getT2AddrModeImm8OpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getT2AddrModeImm8s4OpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getT2AddrModeImm8OffsetOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getT2AddrModeImm12OffsetOpValue(const MachineInstr &MI,unsigned Op)
|
||||
|
@ -17,10 +17,10 @@ namespace ARM {
|
||||
enum Fixups {
|
||||
// fixup_arm_pcrel_12 - 12-bit PC relative relocation for symbol addresses
|
||||
fixup_arm_pcrel_12 = FirstTargetFixupKind,
|
||||
// fixup_arm_vfp_pcrel_10 - 10-bit PC relative relocation for symbol addresses
|
||||
// used in VFP instructions where the lower 2 bits are not encoded (so it's
|
||||
// encoded as an 8-bit immediate).
|
||||
fixup_arm_vfp_pcrel_10,
|
||||
// fixup_arm_pcrel_10 - 10-bit PC relative relocation for symbol addresses
|
||||
// used in VFP and Thumb2 instructions where the lower 2 bits are not encoded
|
||||
// (so it's encoded as an 8-bit immediate).
|
||||
fixup_arm_pcrel_10,
|
||||
// fixup_arm_brnach - 24-bit PC relative relocation for direct branch
|
||||
// instructions.
|
||||
fixup_arm_branch,
|
||||
|
@ -1010,6 +1010,15 @@ class T2Ii8s4<bit P, bit W, bit load, dag oops, dag iops, InstrItinClass itin,
|
||||
let Inst{22} = 1;
|
||||
let Inst{21} = W;
|
||||
let Inst{20} = load;
|
||||
|
||||
bits<4> Rt;
|
||||
bits<4> Rt2;
|
||||
bits<13> addr;
|
||||
let Inst{15-12} = Rt{3-0};
|
||||
let Inst{11-8} = Rt2{3-0};
|
||||
let Inst{19-16} = addr{12-9};
|
||||
let Inst{23} = addr{8};
|
||||
let Inst{7-0} = addr{7-0};
|
||||
}
|
||||
|
||||
class T2sI<dag oops, dag iops, InstrItinClass itin,
|
||||
|
@ -149,6 +149,7 @@ def t2am_imm8_offset : Operand<i32>,
|
||||
// t2addrmode_imm8s4 := reg +/- (imm8 << 2)
|
||||
def t2addrmode_imm8s4 : Operand<i32> {
|
||||
let PrintMethod = "printT2AddrModeImm8s4Operand";
|
||||
string EncoderMethod = "getT2AddrModeImm8s4OpValue";
|
||||
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
|
||||
}
|
||||
|
||||
@ -1263,17 +1264,11 @@ defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
|
||||
defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
|
||||
UnOpFrag<(sextloadi8 node:$Src)>>;
|
||||
|
||||
let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
|
||||
isCodeGenOnly = 1 in { // $dst doesn't exist in asmstring?
|
||||
let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
|
||||
// Load doubleword
|
||||
def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
|
||||
def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$Rt, rGPR:$Rt2),
|
||||
(ins t2addrmode_imm8s4:$addr),
|
||||
IIC_iLoad_d_i, "ldrd", "\t$dst1, $addr", []>;
|
||||
def t2LDRDpci : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2),
|
||||
(ins i32imm:$addr), IIC_iLoad_d_i,
|
||||
"ldrd", "\t$dst1, $addr", []> {
|
||||
let Inst{19-16} = 0b1111; // Rn
|
||||
}
|
||||
IIC_iLoad_d_i, "ldrd", "\t$Rt, $Rt2, $addr", []>;
|
||||
} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1
|
||||
|
||||
// zextload i1 -> zextload i8
|
||||
@ -1431,11 +1426,10 @@ defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
|
||||
BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
|
||||
|
||||
// Store doubleword
|
||||
let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
|
||||
isCodeGenOnly = 1 in // $src2 doesn't exist in asm string
|
||||
let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
|
||||
def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
|
||||
(ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
|
||||
IIC_iStore_d_r, "strd", "\t$src1, $addr", []>;
|
||||
(ins GPR:$Rt, GPR:$Rt2, t2addrmode_imm8s4:$addr),
|
||||
IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", []>;
|
||||
|
||||
// Indexed stores
|
||||
def t2STR_PRE : T2Iidxst<0, 0b10, 1, (outs GPR:$base_wb),
|
||||
@ -1509,21 +1503,21 @@ def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
|
||||
// ldrd / strd pre / post variants
|
||||
// For disassembly only.
|
||||
|
||||
def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$dst1, GPR:$dst2),
|
||||
def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$Rt, GPR:$Rt2),
|
||||
(ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
|
||||
"ldrd", "\t$dst1, $dst2, [$base, $imm]!", []>;
|
||||
"ldrd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
|
||||
|
||||
def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$dst1, GPR:$dst2),
|
||||
def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$Rt, GPR:$Rt2),
|
||||
(ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
|
||||
"ldrd", "\t$dst1, $dst2, [$base], $imm", []>;
|
||||
"ldrd", "\t$Rt, $Rt2, [$base], $imm", []>;
|
||||
|
||||
def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
|
||||
(ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
|
||||
IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base, $imm]!", []>;
|
||||
(ins GPR:$Rt, GPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
|
||||
IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
|
||||
|
||||
def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
|
||||
(ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
|
||||
IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base], $imm", []>;
|
||||
(ins GPR:$Rt, GPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
|
||||
IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base], $imm", []>;
|
||||
|
||||
// T2Ipl (Preload Data/Instruction) signals the memory system of possible future
|
||||
// data/instruction access. These are for disassembly only.
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
const static MCFixupKindInfo Infos[] = {
|
||||
// name offset bits flags
|
||||
{ "fixup_arm_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_arm_vfp_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_arm_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_arm_movt_hi16", 0, 16, 0 },
|
||||
{ "fixup_arm_movw_lo16", 0, 16, 0 },
|
||||
@ -90,6 +90,12 @@ public:
|
||||
uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
/// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
|
||||
/// operand.
|
||||
uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
|
||||
/// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
|
||||
/// operand as needed by load/store instructions.
|
||||
uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
@ -422,6 +428,40 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
return Binary;
|
||||
}
|
||||
|
||||
/// getT2AddrModeImm8s4OpValue - Return encoding info for
|
||||
/// 'reg +/- imm8<<2' operand.
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
// {17-13} = reg
|
||||
// {12} = (U)nsigned (add == '1', sub == '0')
|
||||
// {11-0} = imm8
|
||||
unsigned Reg, Imm8;
|
||||
bool isAdd = true;
|
||||
// If The first operand isn't a register, we have a label reference.
|
||||
const MCOperand &MO = MI.getOperand(OpIdx);
|
||||
if (!MO.isReg()) {
|
||||
Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC.
|
||||
Imm8 = 0;
|
||||
isAdd = false ; // 'U' bit is set as part of the fixup.
|
||||
|
||||
assert(MO.isExpr() && "Unexpected machine operand type!");
|
||||
const MCExpr *Expr = MO.getExpr();
|
||||
MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
|
||||
Fixups.push_back(MCFixup::Create(0, Expr, Kind));
|
||||
|
||||
++MCNumCPRelocations;
|
||||
} else
|
||||
isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
|
||||
|
||||
uint32_t Binary = (Imm8 >> 2) & 0xff;
|
||||
// Immediate is always encoded as positive. The 'U' bit controls add vs sub.
|
||||
if (isAdd)
|
||||
Binary |= (1 << 9);
|
||||
Binary |= (Reg << 9);
|
||||
return Binary;
|
||||
}
|
||||
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getMovtImmOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
@ -613,7 +653,7 @@ getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
|
||||
assert(MO.isExpr() && "Unexpected machine operand type!");
|
||||
const MCExpr *Expr = MO.getExpr();
|
||||
MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_vfp_pcrel_10);
|
||||
MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_12);
|
||||
Fixups.push_back(MCFixup::Create(0, Expr, Kind));
|
||||
|
||||
++MCNumCPRelocations;
|
||||
|
@ -253,9 +253,6 @@ static unsigned T2Morph2LoadLiteral(unsigned Opcode) {
|
||||
default:
|
||||
return Opcode; // Return unmorphed opcode.
|
||||
|
||||
case ARM::t2LDRDi8:
|
||||
return ARM::t2LDRDpci;
|
||||
|
||||
case ARM::t2LDR_POST: case ARM::t2LDR_PRE:
|
||||
case ARM::t2LDRi12: case ARM::t2LDRi8:
|
||||
case ARM::t2LDRs: case ARM::t2LDRT:
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
define i64 @t(i64 %a) nounwind readonly {
|
||||
entry:
|
||||
;CHECK: ldrd r2, [r2]
|
||||
;CHECK: ldrd r2, r3, [r2]
|
||||
%0 = load i64** @b, align 4
|
||||
%1 = load i64* %0, align 4
|
||||
%2 = mul i64 %1, %a
|
||||
|
@ -63,7 +63,7 @@
|
||||
# CHECK: ssat r0, #17, r12
|
||||
0x0c 0xf3 0x10 0x00
|
||||
|
||||
# CHECK: strd r0, [r7, #64]
|
||||
# CHECK: strd r0, r1, [r7, #64]
|
||||
0xc7 0xe9 0x10 0x01
|
||||
|
||||
# CHECK: sub sp, #60
|
||||
|
Loading…
Reference in New Issue
Block a user