mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 06:32:24 +00:00
First stab at providing correct Thumb2 encodings, start with adc.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118924 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
88c3df7afb
commit
5de6d841a5
@ -173,8 +173,12 @@ namespace {
|
||||
const { return 0; }
|
||||
unsigned getSOImmOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getT2SOImmOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getSORegOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op)
|
||||
|
@ -31,6 +31,7 @@ def tb_addrmode : Operand<i32> {
|
||||
def t2_so_reg : Operand<i32>, // reg imm
|
||||
ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
|
||||
[shl,srl,sra,rotr]> {
|
||||
string EncoderMethod = "getT2SORegOpValue";
|
||||
let PrintMethod = "printT2SOOperand";
|
||||
let MIOperandInfo = (ops rGPR, i32imm);
|
||||
}
|
||||
@ -51,7 +52,9 @@ def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
|
||||
// represented in the imm field in the same 12-bit form that they are encoded
|
||||
// into t2_so_imm instructions: the 8-bit immediate is the least significant
|
||||
// bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
|
||||
def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]>;
|
||||
def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]> {
|
||||
string EncoderMethod = "getT2SOImmOpValue";
|
||||
}
|
||||
|
||||
// t2_so_imm_not - Match an immediate that is a complement
|
||||
// of a t2_so_imm.
|
||||
@ -167,6 +170,47 @@ def t2addrmode_so_reg : Operand<i32>,
|
||||
// Multiclass helpers...
|
||||
//
|
||||
|
||||
class T2TwoRegShiftedImm<dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: T2sI<oops, iops, itin, opc, asm, pattern> {
|
||||
bits<4> Rd;
|
||||
bits<4> Rn;
|
||||
bits<12> imm;
|
||||
|
||||
let Inst{11-8} = Rd{3-0};
|
||||
let Inst{19-16} = Rn{3-0};
|
||||
let Inst{26} = imm{11};
|
||||
let Inst{14-12} = imm{10-8};
|
||||
let Inst{7-0} = imm{7-0};
|
||||
}
|
||||
|
||||
class T2ThreeReg<dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: T2sI<oops, iops, itin, opc, asm, pattern> {
|
||||
bits<4> Rd;
|
||||
bits<4> Rn;
|
||||
bits<4> Rm;
|
||||
|
||||
let Inst{11-8} = Rd{3-0};
|
||||
let Inst{19-16} = Rn{3-0};
|
||||
let Inst{3-0} = Rm{3-0};
|
||||
}
|
||||
|
||||
class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: T2sI<oops, iops, itin, opc, asm, pattern> {
|
||||
bits<4> Rd;
|
||||
bits<4> Rn;
|
||||
bits<12> ShiftedRm;
|
||||
|
||||
let Inst{11-8} = Rd{3-0};
|
||||
let Inst{19-16} = Rn{3-0};
|
||||
let Inst{3-0} = ShiftedRm{3-0};
|
||||
let Inst{5-4} = ShiftedRm{6-5};
|
||||
let Inst{14-12} = ShiftedRm{11-9};
|
||||
let Inst{7-6} = ShiftedRm{8-7};
|
||||
}
|
||||
|
||||
/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
|
||||
/// unary operation that produces a value. These are predicable and can be
|
||||
/// changed to modify CPSR.
|
||||
@ -399,9 +443,9 @@ let Uses = [CPSR] in {
|
||||
multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
|
||||
bit Commutable = 0> {
|
||||
// shifted imm
|
||||
def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
|
||||
opc, "\t$dst, $lhs, $rhs",
|
||||
[(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_imm:$rhs))]>,
|
||||
def ri : T2TwoRegShiftedImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
|
||||
IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
|
||||
[(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
|
||||
Requires<[IsThumb2]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25} = 0;
|
||||
@ -410,9 +454,9 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
|
||||
let Inst{15} = 0;
|
||||
}
|
||||
// register
|
||||
def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iALUr,
|
||||
opc, ".w\t$dst, $lhs, $rhs",
|
||||
[(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]>,
|
||||
def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
|
||||
opc, ".w\t$Rd, $Rn, $Rm",
|
||||
[(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
|
||||
Requires<[IsThumb2]> {
|
||||
let isCommutable = Commutable;
|
||||
let Inst{31-27} = 0b11101;
|
||||
@ -424,9 +468,10 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
|
||||
let Inst{5-4} = 0b00; // type
|
||||
}
|
||||
// shifted register
|
||||
def rs : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
|
||||
opc, ".w\t$dst, $lhs, $rhs",
|
||||
[(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_reg:$rhs))]>,
|
||||
def rs : T2TwoRegShiftedReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
|
||||
IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
|
||||
[(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
|
||||
Requires<[IsThumb2]> {
|
||||
let Inst{31-27} = 0b11101;
|
||||
let Inst{26-25} = 0b01;
|
||||
@ -440,9 +485,10 @@ let Defs = [CPSR] in {
|
||||
multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
|
||||
bit Commutable = 0> {
|
||||
// shifted imm
|
||||
def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
|
||||
opc, "\t$dst, $lhs, $rhs",
|
||||
[(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_imm:$rhs))]>,
|
||||
def ri : T2TwoRegShiftedImm<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
|
||||
opc, "\t$Rd, $Rn, $imm",
|
||||
[(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
|
||||
Requires<[IsThumb2]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25} = 0;
|
||||
@ -451,9 +497,9 @@ multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
|
||||
let Inst{15} = 0;
|
||||
}
|
||||
// register
|
||||
def rr : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), IIC_iALUr,
|
||||
opc, ".w\t$dst, $lhs, $rhs",
|
||||
[(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]>,
|
||||
def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
|
||||
opc, ".w\t$Rd, $Rn, $Rm",
|
||||
[(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
|
||||
Requires<[IsThumb2]> {
|
||||
let isCommutable = Commutable;
|
||||
let Inst{31-27} = 0b11101;
|
||||
@ -465,9 +511,10 @@ multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
|
||||
let Inst{5-4} = 0b00; // type
|
||||
}
|
||||
// shifted register
|
||||
def rs : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
|
||||
opc, ".w\t$dst, $lhs, $rhs",
|
||||
[(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_reg:$rhs))]>,
|
||||
def rs : T2TwoRegShiftedReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
|
||||
IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
|
||||
[(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
|
||||
Requires<[IsThumb2]> {
|
||||
let Inst{31-27} = 0b11101;
|
||||
let Inst{26-25} = 0b01;
|
||||
|
@ -137,9 +137,20 @@ public:
|
||||
return Binary;
|
||||
}
|
||||
|
||||
/// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
|
||||
unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
unsigned SoImm = MI.getOperand(Op).getImm();
|
||||
unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm);
|
||||
assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
|
||||
return Encoded;
|
||||
}
|
||||
|
||||
/// getSORegOpValue - Return an encoded so_reg shifted register value.
|
||||
unsigned getSORegOpValue(const MCInst &MI, unsigned Op,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
unsigned getRotImmOpValue(const MCInst &MI, unsigned Op,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
@ -548,6 +559,47 @@ getSORegOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
|
||||
}
|
||||
|
||||
unsigned ARMMCCodeEmitter::
|
||||
getT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
// Sub-operands are [reg, imm]. The first register is Rm, the reg to be
|
||||
// shifted. The second is the amount to shift by.
|
||||
//
|
||||
// {3-0} = Rm.
|
||||
// {4} = 0
|
||||
// {6-5} = type
|
||||
// {11-7} = imm
|
||||
|
||||
const MCOperand &MO = MI.getOperand(OpIdx);
|
||||
const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
|
||||
ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
|
||||
|
||||
// Encode Rm.
|
||||
unsigned Binary = getARMRegisterNumbering(MO.getReg());
|
||||
|
||||
// Encode the shift opcode.
|
||||
unsigned SBits = 0;
|
||||
// Set shift operand (bit[6:4]).
|
||||
// LSL - 000
|
||||
// LSR - 010
|
||||
// ASR - 100
|
||||
// ROR - 110
|
||||
switch (SOpc) {
|
||||
default: llvm_unreachable("Unknown shift opc!");
|
||||
case ARM_AM::lsl: SBits = 0x0; break;
|
||||
case ARM_AM::lsr: SBits = 0x2; break;
|
||||
case ARM_AM::asr: SBits = 0x4; break;
|
||||
case ARM_AM::ror: SBits = 0x6; break;
|
||||
}
|
||||
|
||||
Binary |= SBits << 4;
|
||||
if (SOpc == ARM_AM::rrx)
|
||||
return Binary;
|
||||
|
||||
// Encode shift_imm bit[11:7].
|
||||
return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
|
||||
}
|
||||
|
||||
unsigned ARMMCCodeEmitter::
|
||||
getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
|
14
test/MC/ARM/thumb2.s
Normal file
14
test/MC/ARM/thumb2.s
Normal file
@ -0,0 +1,14 @@
|
||||
@ RUN: llvm-mc -mcpu=cortex-a8 -triple thumb-unknown-unknown -show-encoding < %s | FileCheck %s
|
||||
@ XFAIL: *
|
||||
.code 16
|
||||
|
||||
@ CHECK: adc r1, r1, #171 @ encoding: [0xab,0x01,0x41,0xf1]
|
||||
adc r1, r1, #171
|
||||
@ CHECK: adc r1, r1, #1179666 @ encoding: [0x12,0x11,0x41,0xf1]
|
||||
adc r1, r1, #1179666
|
||||
@ CHECK: adc r1, r1, #872428544 @ encoding: [0x34,0x21,0x41,0xf1]
|
||||
adc r1, r1, #872428544
|
||||
@ CHECK: adc r1, r1, #1448498774 @ encoding: [0x56,0x31,0x41,0xf1]
|
||||
adc r1, r1, #1448498774
|
||||
@ CHECK: adc r1, r1, #66846720 @ encoding: [0x7f,0x71,0x41,0xf1]
|
||||
adc r1, r1, #66846720
|
Loading…
x
Reference in New Issue
Block a user