mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-19 06:31:18 +00:00
ARM Assembly support for Thumb mov-immediate.
Correctly parse the forms of the Thumb mov-immediate instruction: 1. 8-bit immediate 0-255. 2. 12-bit shifted-immediate. The 16-bit immediate "movw" form is also legal with just a "mov" mnemonic, but is not yet supported. More parser logic necessary there due to fixups. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133966 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4db3748fcf
commit
6b8f1e35ea
@ -34,9 +34,10 @@ def imm0_7_neg : PatLeaf<(i32 imm), [{
|
|||||||
return (uint32_t)-N->getZExtValue() < 8;
|
return (uint32_t)-N->getZExtValue() < 8;
|
||||||
}], imm_neg_XFORM>;
|
}], imm_neg_XFORM>;
|
||||||
|
|
||||||
def imm0_255 : ImmLeaf<i32, [{
|
def imm0_255_asmoperand : AsmOperandClass { let Name = "Imm0_255"; }
|
||||||
return Imm >= 0 && Imm < 256;
|
def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> {
|
||||||
}]>;
|
let ParserMatchClass = imm0_255_asmoperand;
|
||||||
|
}
|
||||||
def imm0_255_comp : PatLeaf<(i32 imm), [{
|
def imm0_255_comp : PatLeaf<(i32 imm), [{
|
||||||
return ~((uint32_t)N->getZExtValue()) < 256;
|
return ~((uint32_t)N->getZExtValue()) < 256;
|
||||||
}]>;
|
}]>;
|
||||||
@ -1072,7 +1073,7 @@ def tLSRrr : // A8.6.91
|
|||||||
|
|
||||||
// Move register
|
// Move register
|
||||||
let isMoveImm = 1 in
|
let isMoveImm = 1 in
|
||||||
def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins i32imm:$imm8), IIC_iMOVi,
|
def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins imm0_255:$imm8), IIC_iMOVi,
|
||||||
"mov", "\t$Rd, $imm8",
|
"mov", "\t$Rd, $imm8",
|
||||||
[(set tGPR:$Rd, imm0_255:$imm8)]>,
|
[(set tGPR:$Rd, imm0_255:$imm8)]>,
|
||||||
T1General<{1,0,0,?,?}> {
|
T1General<{1,0,0,?,?}> {
|
||||||
|
@ -44,9 +44,11 @@ def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
|
|||||||
// t2_so_imm - Match a 32-bit immediate operand, which is an
|
// t2_so_imm - Match a 32-bit immediate operand, which is an
|
||||||
// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
|
// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
|
||||||
// immediate splatted into multiple bytes of the word.
|
// immediate splatted into multiple bytes of the word.
|
||||||
|
def t2_so_imm_asmoperand : AsmOperandClass { let Name = "T2SOImm"; }
|
||||||
def t2_so_imm : Operand<i32>, ImmLeaf<i32, [{
|
def t2_so_imm : Operand<i32>, ImmLeaf<i32, [{
|
||||||
return ARM_AM::getT2SOImmVal(Imm) != -1;
|
return ARM_AM::getT2SOImmVal(Imm) != -1;
|
||||||
}]> {
|
}]> {
|
||||||
|
let ParserMatchClass = t2_so_imm_asmoperand;
|
||||||
let EncoderMethod = "getT2SOImmOpValue";
|
let EncoderMethod = "getT2SOImmOpValue";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1645,6 +1647,10 @@ def t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi,
|
|||||||
let Inst{15} = 0;
|
let Inst{15} = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def : InstAlias<"mov${s}${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm,
|
||||||
|
pred:$p, cc_out:$s)>,
|
||||||
|
Requires<[IsThumb2]>;
|
||||||
|
|
||||||
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
|
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
|
||||||
def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins i32imm_hilo16:$imm), IIC_iMOVi,
|
def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins i32imm_hilo16:$imm), IIC_iMOVi,
|
||||||
"movw", "\t$Rd, $imm",
|
"movw", "\t$Rd, $imm",
|
||||||
@ -2709,6 +2715,8 @@ def t2MOVCCr : T2TwoReg<
|
|||||||
let Inst{7-4} = 0b0000;
|
let Inst{7-4} = 0b0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Pseudo-ize these. For now, just mark codegen only.
|
||||||
|
let isCodeGenOnly = 1 in {
|
||||||
let isMoveImm = 1 in
|
let isMoveImm = 1 in
|
||||||
def t2MOVCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
|
def t2MOVCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
|
||||||
IIC_iCMOVi, "mov", ".w\t$Rd, $imm",
|
IIC_iCMOVi, "mov", ".w\t$Rd, $imm",
|
||||||
@ -2789,6 +2797,7 @@ def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd),
|
|||||||
IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>,
|
IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>,
|
||||||
RegConstraint<"$false = $Rd">;
|
RegConstraint<"$false = $Rd">;
|
||||||
} // neverHasSideEffects
|
} // neverHasSideEffects
|
||||||
|
} // isCodeGenOnly = 1
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Atomic operations intrinsics
|
// Atomic operations intrinsics
|
||||||
|
@ -350,6 +350,22 @@ public:
|
|||||||
bool isCondCode() const { return Kind == CondCode; }
|
bool isCondCode() const { return Kind == CondCode; }
|
||||||
bool isCCOut() const { return Kind == CCOut; }
|
bool isCCOut() const { return Kind == CCOut; }
|
||||||
bool isImm() const { return Kind == Immediate; }
|
bool isImm() const { return Kind == Immediate; }
|
||||||
|
bool isImm0_255() const {
|
||||||
|
if (Kind != Immediate)
|
||||||
|
return false;
|
||||||
|
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
|
||||||
|
if (!CE) return false;
|
||||||
|
int64_t Value = CE->getValue();
|
||||||
|
return Value >= 0 && Value < 256;
|
||||||
|
}
|
||||||
|
bool isT2SOImm() const {
|
||||||
|
if (Kind != Immediate)
|
||||||
|
return false;
|
||||||
|
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
|
||||||
|
if (!CE) return false;
|
||||||
|
int64_t Value = CE->getValue();
|
||||||
|
return ARM_AM::getT2SOImmVal(Value) != -1;
|
||||||
|
}
|
||||||
bool isReg() const { return Kind == Register; }
|
bool isReg() const { return Kind == Register; }
|
||||||
bool isRegList() const { return Kind == RegisterList; }
|
bool isRegList() const { return Kind == RegisterList; }
|
||||||
bool isDPRRegList() const { return Kind == DPRRegisterList; }
|
bool isDPRRegList() const { return Kind == DPRRegisterList; }
|
||||||
@ -515,6 +531,16 @@ public:
|
|||||||
addExpr(Inst, getImm());
|
addExpr(Inst, getImm());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addImm0_255Operands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
|
addExpr(Inst, getImm());
|
||||||
|
}
|
||||||
|
|
||||||
|
void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
|
addExpr(Inst, getImm());
|
||||||
|
}
|
||||||
|
|
||||||
void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
|
void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
|
||||||
assert(N == 1 && "Invalid number of operands!");
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
|
Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
|
||||||
|
@ -49,6 +49,22 @@
|
|||||||
@ CHECK: mov.w r0, #66846720 @ encoding: [0x7f,0x70,0x4f,0xf0]
|
@ CHECK: mov.w r0, #66846720 @ encoding: [0x7f,0x70,0x4f,0xf0]
|
||||||
mov.w r0, #66846720
|
mov.w r0, #66846720
|
||||||
|
|
||||||
|
@ Aliases w/ the vanilla 'mov' mnemonic, and explicit alternative selection.
|
||||||
|
mov r2, #0xbf000000
|
||||||
|
mov r1, #0x100
|
||||||
|
mov r3, #32
|
||||||
|
mov.w r3, #32
|
||||||
|
movw r3, #32
|
||||||
|
|
||||||
|
@ CHECK: mov.w r2, #3204448256 @ encoding: [0x4f,0xf0,0x3f,0x42]
|
||||||
|
@ CHECK: mov.w r1, #256 @ encoding: [0x4f,0xf4,0x80,0x71]
|
||||||
|
@ CHECK: mov r3, #32 @ encoding: [0x20,0x23]
|
||||||
|
@ CHECK: mov.w r3, #32 @ encoding: [0x4f,0xf0,0x20,0x03]
|
||||||
|
@ CHECK: movw r3, #32 @ encoding: [0x40,0xf2,0x20,0x03]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ CHECK: rrx r0, r0 @ encoding: [0x30,0x00,0x4f,0xea]
|
@ CHECK: rrx r0, r0 @ encoding: [0x30,0x00,0x4f,0xea]
|
||||||
rrx r0, r0
|
rrx r0, r0
|
||||||
|
|
||||||
|
@ -588,6 +588,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
|
|||||||
IMM("imm0_31");
|
IMM("imm0_31");
|
||||||
IMM("imm0_31_m1");
|
IMM("imm0_31_m1");
|
||||||
IMM("nModImm");
|
IMM("nModImm");
|
||||||
|
IMM("imm0_255");
|
||||||
IMM("imm0_4095");
|
IMM("imm0_4095");
|
||||||
IMM("jt2block_operand");
|
IMM("jt2block_operand");
|
||||||
IMM("t_imm_s4");
|
IMM("t_imm_s4");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user