mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
Add ARM mode encoding for [SU]XT[BH] and [SU]XTA[BH] instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116421 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e822f94509
commit
b35ad41fef
@ -170,6 +170,8 @@ namespace {
|
||||
const { return 0; }
|
||||
unsigned getSORegOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
|
||||
/// getMovi32Value - Return binary encoding of operand for movw/movt. If the
|
||||
/// machine operand requires relocation, record the relocation and return
|
||||
|
@ -933,7 +933,13 @@ class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, itin,
|
||||
opc, asm, "", pattern> {
|
||||
// All AExtI instructions have Rd and Rm register operands.
|
||||
bits<4> Rd;
|
||||
bits<4> Rm;
|
||||
let Inst{15-12} = Rd;
|
||||
let Inst{3-0} = Rm;
|
||||
let Inst{7-4} = 0b0111;
|
||||
let Inst{9-8} = 0b00;
|
||||
let Inst{27-20} = opcod;
|
||||
}
|
||||
|
||||
|
@ -199,12 +199,6 @@ def so_imm_not_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
|
||||
}]>;
|
||||
|
||||
// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
|
||||
def rot_imm : PatLeaf<(i32 imm), [{
|
||||
int32_t v = (int32_t)N->getZExtValue();
|
||||
return v == 8 || v == 16 || v == 24;
|
||||
}]>;
|
||||
|
||||
/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
|
||||
def imm1_15 : PatLeaf<(i32 imm), [{
|
||||
return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
|
||||
@ -302,6 +296,13 @@ def pclabel : Operand<i32> {
|
||||
let PrintMethod = "printPCLabel";
|
||||
}
|
||||
|
||||
// rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
|
||||
def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
|
||||
int32_t v = (int32_t)N->getZExtValue();
|
||||
return v == 8 || v == 16 || v == 24; }]> {
|
||||
string EncoderMethod = "getRotImmOpValue";
|
||||
}
|
||||
|
||||
// shift_imm: An integer that encodes a shift amount and the type of shift
|
||||
// (currently either asr or lsl) using the same encoding used for the
|
||||
// immediates in so_reg operands.
|
||||
@ -609,33 +610,37 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc,
|
||||
/// register and one whose operand is a register rotated by 8/16/24.
|
||||
/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
|
||||
multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
|
||||
def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
|
||||
IIC_iEXTr, opc, "\t$dst, $src",
|
||||
[(set GPR:$dst, (opnode GPR:$src))]>,
|
||||
def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
|
||||
IIC_iEXTr, opc, "\t$Rd, $Rm",
|
||||
[(set GPR:$Rd, (opnode GPR:$Rm))]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{11-10} = 0b00;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
|
||||
IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
|
||||
[(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
|
||||
def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
|
||||
IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
|
||||
[(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
bits<2> rot;
|
||||
let Inst{11-10} = rot;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
}
|
||||
|
||||
multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
|
||||
def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
|
||||
IIC_iEXTr, opc, "\t$dst, $src",
|
||||
def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm),
|
||||
IIC_iEXTr, opc, "\t$Rd, $Rm",
|
||||
[/* For disassembly only; pattern left blank */]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{11-10} = 0b00;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
|
||||
IIC_iEXTr, opc, "\t$dst, $src, ror $rot",
|
||||
def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
|
||||
IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
|
||||
[/* For disassembly only; pattern left blank */]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
bits<2> rot;
|
||||
let Inst{11-10} = rot;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
}
|
||||
@ -643,33 +648,43 @@ multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
|
||||
/// AI_exta_rrot - A binary operation with two forms: one whose operand is a
|
||||
/// register and one whose operand is a register rotated by 8/16/24.
|
||||
multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
|
||||
def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
|
||||
IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
|
||||
[(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
|
||||
def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
|
||||
IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
|
||||
[(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{11-10} = 0b00;
|
||||
}
|
||||
def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
|
||||
i32imm:$rot),
|
||||
IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
|
||||
[(set GPR:$dst, (opnode GPR:$LHS,
|
||||
(rotr GPR:$RHS, rot_imm:$rot)))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
|
||||
rot_imm:$rot),
|
||||
IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
|
||||
[(set GPR:$Rd, (opnode GPR:$Rn,
|
||||
(rotr GPR:$Rm, rot_imm:$rot)))]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
bits<4> Rn;
|
||||
bits<2> rot;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{11-10} = rot;
|
||||
}
|
||||
}
|
||||
|
||||
// For disassembly only.
|
||||
multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
|
||||
def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
|
||||
IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS",
|
||||
def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
|
||||
IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm",
|
||||
[/* For disassembly only; pattern left blank */]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{11-10} = 0b00;
|
||||
}
|
||||
def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
|
||||
i32imm:$rot),
|
||||
IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot",
|
||||
def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
|
||||
rot_imm:$rot),
|
||||
IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
|
||||
[/* For disassembly only; pattern left blank */]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
Requires<[IsARM, HasV6]> {
|
||||
bits<4> Rn;
|
||||
bits<2> rot;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{11-10} = rot;
|
||||
}
|
||||
}
|
||||
|
||||
/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
|
||||
|
@ -74,6 +74,16 @@ public:
|
||||
/// getSORegOpValue - Return an encoded so_reg shifted register value.
|
||||
unsigned getSORegOpValue(const MCInst &MI, unsigned Op) const;
|
||||
|
||||
unsigned getRotImmOpValue(const MCInst &MI, unsigned Op) const {
|
||||
switch (MI.getOperand(Op).getImm()) {
|
||||
default: assert (0 && "Not a valid rot_imm value!");
|
||||
case 0: return 0;
|
||||
case 8: return 1;
|
||||
case 16: return 2;
|
||||
case 24: return 3;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned getNumFixupKinds() const {
|
||||
assert(0 && "ARMMCCodeEmitter::getNumFixupKinds() not yet implemented.");
|
||||
return 0;
|
||||
|
@ -64,4 +64,14 @@ entry:
|
||||
%add = add nsw i64 %b, %a
|
||||
ret i64 %add
|
||||
}
|
||||
|
||||
define i32 @f7(i32 %a, i32 %b) nounwind readnone optsize ssp {
|
||||
entry:
|
||||
; CHECK: f7
|
||||
; CHECK: uxtab r0, r0, r1 @ encoding: [0x71,0x00,0xe0,0xe6]
|
||||
%and = and i32 %b, 255
|
||||
%add = add i32 %and, %a
|
||||
ret i32 %add
|
||||
}
|
||||
|
||||
declare void @llvm.trap() nounwind
|
||||
|
@ -585,6 +585,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
|
||||
MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I
|
||||
MISC("t2_so_reg", "kOperandTypeThumb2SoReg"); // R, I
|
||||
MISC("so_imm", "kOperandTypeARMSoImm"); // I
|
||||
MISC("rot_imm", "kOperandTypeARMRotImm"); // I
|
||||
MISC("t2_so_imm", "kOperandTypeThumb2SoImm"); // I
|
||||
MISC("so_imm2part", "kOperandTypeARMSoImm2Part"); // I
|
||||
MISC("pred", "kOperandTypeARMPredicate"); // I, R
|
||||
@ -801,6 +802,7 @@ static void emitCommonEnums(raw_ostream &o, unsigned int &i) {
|
||||
operandTypes.addEntry("kOperandTypeARMBranchTarget");
|
||||
operandTypes.addEntry("kOperandTypeARMSoReg");
|
||||
operandTypes.addEntry("kOperandTypeARMSoImm");
|
||||
operandTypes.addEntry("kOperandTypeARMRotImm");
|
||||
operandTypes.addEntry("kOperandTypeARMSoImm2Part");
|
||||
operandTypes.addEntry("kOperandTypeARMPredicate");
|
||||
operandTypes.addEntry("kOperandTypeARMAddrMode2");
|
||||
|
Loading…
Reference in New Issue
Block a user