mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
ARM assembler aliases for "add Rd, #-imm" to "sub Rd, #imm".
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146111 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7bf7fecd8d
commit
3bc8a3d3af
@ -243,17 +243,18 @@ def imm16_31 : ImmLeaf<i32, [{
|
|||||||
return (int32_t)Imm >= 16 && (int32_t)Imm < 32;
|
return (int32_t)Imm >= 16 && (int32_t)Imm < 32;
|
||||||
}]>;
|
}]>;
|
||||||
|
|
||||||
def so_imm_neg :
|
def so_imm_neg_asmoperand : AsmOperandClass { let Name = "ARMSOImmNeg"; }
|
||||||
PatLeaf<(imm), [{
|
def so_imm_neg : Operand<i32>, PatLeaf<(imm), [{
|
||||||
return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
|
return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
|
||||||
}], so_imm_neg_XFORM>;
|
}], so_imm_neg_XFORM> {
|
||||||
|
let ParserMatchClass = so_imm_neg_asmoperand;
|
||||||
|
}
|
||||||
|
|
||||||
// Note: this pattern doesn't require an encoder method and such, as it's
|
// Note: this pattern doesn't require an encoder method and such, as it's
|
||||||
// only used on aliases (Pat<> and InstAlias<>). The actual encoding
|
// only used on aliases (Pat<> and InstAlias<>). The actual encoding
|
||||||
// is handled by the destination instructions, which use t2_so_imm.
|
// is handled by the destination instructions, which use t2_so_imm.
|
||||||
def so_imm_not_asmoperand : AsmOperandClass { let Name = "ARMSOImmNot"; }
|
def so_imm_not_asmoperand : AsmOperandClass { let Name = "ARMSOImmNot"; }
|
||||||
def so_imm_not :
|
def so_imm_not : Operand<i32>, PatLeaf<(imm), [{
|
||||||
Operand<i32>, PatLeaf<(imm), [{
|
|
||||||
return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
|
return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
|
||||||
}], so_imm_not_XFORM> {
|
}], so_imm_not_XFORM> {
|
||||||
let ParserMatchClass = so_imm_not_asmoperand;
|
let ParserMatchClass = so_imm_not_asmoperand;
|
||||||
@ -5041,6 +5042,11 @@ def : MnemonicAlias<"usubaddx", "usax">;
|
|||||||
// for isel.
|
// for isel.
|
||||||
def : ARMInstAlias<"mov${s}${p} $Rd, $imm",
|
def : ARMInstAlias<"mov${s}${p} $Rd, $imm",
|
||||||
(MVNi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>;
|
(MVNi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>;
|
||||||
|
// Likewise, "add Rd, so_imm_neg" -> sub
|
||||||
|
def : ARMInstAlias<"add${s}${p} $Rd, $Rn, $imm",
|
||||||
|
(SUBri GPR:$Rd, GPR:$Rn, so_imm_neg:$imm, pred:$p, cc_out:$s)>;
|
||||||
|
def : ARMInstAlias<"add${s}${p} $Rd, $imm",
|
||||||
|
(SUBri GPR:$Rd, GPR:$Rd, so_imm_neg:$imm, pred:$p, cc_out:$s)>;
|
||||||
|
|
||||||
// The shifter forms of the MOV instruction are aliased to the ASR, LSL,
|
// The shifter forms of the MOV instruction are aliased to the ASR, LSL,
|
||||||
// LSR, ROR, and RRX instructions.
|
// LSR, ROR, and RRX instructions.
|
||||||
|
@ -80,18 +80,19 @@ def t2_so_imm : Operand<i32>, ImmLeaf<i32, [{
|
|||||||
// only used on aliases (Pat<> and InstAlias<>). The actual encoding
|
// only used on aliases (Pat<> and InstAlias<>). The actual encoding
|
||||||
// is handled by the destination instructions, which use t2_so_imm.
|
// is handled by the destination instructions, which use t2_so_imm.
|
||||||
def t2_so_imm_not_asmoperand : AsmOperandClass { let Name = "T2SOImmNot"; }
|
def t2_so_imm_not_asmoperand : AsmOperandClass { let Name = "T2SOImmNot"; }
|
||||||
def t2_so_imm_not : Operand<i32>,
|
def t2_so_imm_not : Operand<i32>, PatLeaf<(imm), [{
|
||||||
PatLeaf<(imm), [{
|
|
||||||
return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
|
return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
|
||||||
}], t2_so_imm_not_XFORM> {
|
}], t2_so_imm_not_XFORM> {
|
||||||
let ParserMatchClass = t2_so_imm_not_asmoperand;
|
let ParserMatchClass = t2_so_imm_not_asmoperand;
|
||||||
}
|
}
|
||||||
|
|
||||||
// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
|
// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
|
||||||
def t2_so_imm_neg : Operand<i32>,
|
def t2_so_imm_neg_asmoperand : AsmOperandClass { let Name = "T2SOImmNeg"; }
|
||||||
PatLeaf<(imm), [{
|
def t2_so_imm_neg : Operand<i32>, PatLeaf<(imm), [{
|
||||||
return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1;
|
return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1;
|
||||||
}], t2_so_imm_neg_XFORM>;
|
}], t2_so_imm_neg_XFORM> {
|
||||||
|
let ParserMatchClass = t2_so_imm_neg_asmoperand;
|
||||||
|
}
|
||||||
|
|
||||||
/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
|
/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
|
||||||
def imm0_4095 : Operand<i32>,
|
def imm0_4095 : Operand<i32>,
|
||||||
@ -4096,6 +4097,13 @@ def : t2InstAlias<"sxth${p} $Rd, $Rm$rot",
|
|||||||
// for isel.
|
// for isel.
|
||||||
def : t2InstAlias<"mov${p} $Rd, $imm",
|
def : t2InstAlias<"mov${p} $Rd, $imm",
|
||||||
(t2MVNi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>;
|
(t2MVNi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>;
|
||||||
|
// Likewise, "add Rd, so_imm_neg" -> sub
|
||||||
|
def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
|
||||||
|
(t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm,
|
||||||
|
pred:$p, cc_out:$s)>;
|
||||||
|
def : t2InstAlias<"add${s}${p} $Rd, $imm",
|
||||||
|
(t2SUBri GPRnopc:$Rd, GPRnopc:$Rd, t2_so_imm_neg:$imm,
|
||||||
|
pred:$p, cc_out:$s)>;
|
||||||
|
|
||||||
|
|
||||||
// Wide 'mul' encoding can be specified with only two operands.
|
// Wide 'mul' encoding can be specified with only two operands.
|
||||||
|
@ -749,6 +749,14 @@ public:
|
|||||||
int64_t Value = CE->getValue();
|
int64_t Value = CE->getValue();
|
||||||
return ARM_AM::getSOImmVal(~Value) != -1;
|
return ARM_AM::getSOImmVal(~Value) != -1;
|
||||||
}
|
}
|
||||||
|
bool isARMSOImmNeg() const {
|
||||||
|
if (Kind != k_Immediate)
|
||||||
|
return false;
|
||||||
|
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
|
||||||
|
if (!CE) return false;
|
||||||
|
int64_t Value = CE->getValue();
|
||||||
|
return ARM_AM::getSOImmVal(-Value) != -1;
|
||||||
|
}
|
||||||
bool isT2SOImm() const {
|
bool isT2SOImm() const {
|
||||||
if (Kind != k_Immediate)
|
if (Kind != k_Immediate)
|
||||||
return false;
|
return false;
|
||||||
@ -765,6 +773,14 @@ public:
|
|||||||
int64_t Value = CE->getValue();
|
int64_t Value = CE->getValue();
|
||||||
return ARM_AM::getT2SOImmVal(~Value) != -1;
|
return ARM_AM::getT2SOImmVal(~Value) != -1;
|
||||||
}
|
}
|
||||||
|
bool isT2SOImmNeg() const {
|
||||||
|
if (Kind != k_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 isSetEndImm() const {
|
bool isSetEndImm() const {
|
||||||
if (Kind != k_Immediate)
|
if (Kind != k_Immediate)
|
||||||
return false;
|
return false;
|
||||||
@ -1321,6 +1337,14 @@ public:
|
|||||||
Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
|
Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
|
// The operand is actually a t2_so_imm, but we have its
|
||||||
|
// negation in the assembly source, so twiddle it here.
|
||||||
|
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
|
||||||
|
Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
|
void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
|
||||||
assert(N == 1 && "Invalid number of operands!");
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
// The operand is actually a so_imm, but we have its bitwise
|
// The operand is actually a so_imm, but we have its bitwise
|
||||||
@ -1329,6 +1353,14 @@ public:
|
|||||||
Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
|
Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
|
// The operand is actually a so_imm, but we have its
|
||||||
|
// negation in the assembly source, so twiddle it here.
|
||||||
|
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
|
||||||
|
Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
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())));
|
||||||
|
@ -173,6 +173,9 @@ Lforward:
|
|||||||
add r6, r7, ror r9
|
add r6, r7, ror r9
|
||||||
add r4, r5, rrx
|
add r4, r5, rrx
|
||||||
|
|
||||||
|
add r0, #-4
|
||||||
|
add r4, r5, #-21
|
||||||
|
|
||||||
@ CHECK: add r4, r5, #61440 @ encoding: [0x0f,0x4a,0x85,0xe2]
|
@ CHECK: add r4, r5, #61440 @ encoding: [0x0f,0x4a,0x85,0xe2]
|
||||||
@ CHECK: add r4, r5, r6 @ encoding: [0x06,0x40,0x85,0xe0]
|
@ CHECK: add r4, r5, r6 @ encoding: [0x06,0x40,0x85,0xe0]
|
||||||
@ CHECK: add r4, r5, r6, lsl #5 @ encoding: [0x86,0x42,0x85,0xe0]
|
@ CHECK: add r4, r5, r6, lsl #5 @ encoding: [0x86,0x42,0x85,0xe0]
|
||||||
@ -187,7 +190,6 @@ Lforward:
|
|||||||
@ CHECK: add r6, r7, r8, ror r9 @ encoding: [0x78,0x69,0x87,0xe0]
|
@ CHECK: add r6, r7, r8, ror r9 @ encoding: [0x78,0x69,0x87,0xe0]
|
||||||
@ CHECK: add r4, r5, r6, rrx @ encoding: [0x66,0x40,0x85,0xe0]
|
@ CHECK: add r4, r5, r6, rrx @ encoding: [0x66,0x40,0x85,0xe0]
|
||||||
|
|
||||||
|
|
||||||
@ CHECK: add r5, r5, #61440 @ encoding: [0x0f,0x5a,0x85,0xe2]
|
@ CHECK: add r5, r5, #61440 @ encoding: [0x0f,0x5a,0x85,0xe2]
|
||||||
@ CHECK: add r4, r4, r5 @ encoding: [0x05,0x40,0x84,0xe0]
|
@ CHECK: add r4, r4, r5 @ encoding: [0x05,0x40,0x84,0xe0]
|
||||||
@ CHECK: add r4, r4, r5, lsl #5 @ encoding: [0x85,0x42,0x84,0xe0]
|
@ CHECK: add r4, r4, r5, lsl #5 @ encoding: [0x85,0x42,0x84,0xe0]
|
||||||
@ -201,6 +203,9 @@ Lforward:
|
|||||||
@ CHECK: add r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0x86,0xe0]
|
@ CHECK: add r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0x86,0xe0]
|
||||||
@ CHECK: add r4, r4, r5, rrx @ encoding: [0x65,0x40,0x84,0xe0]
|
@ CHECK: add r4, r4, r5, rrx @ encoding: [0x65,0x40,0x84,0xe0]
|
||||||
|
|
||||||
|
@ CHECK: sub r0, r0, #4 @ encoding: [0x04,0x00,0x40,0xe2]
|
||||||
|
@ CHECK: sub r4, r5, #21 @ encoding: [0x15,0x40,0x45,0xe2]
|
||||||
|
|
||||||
|
|
||||||
@------------------------------------------------------------------------------
|
@------------------------------------------------------------------------------
|
||||||
@ AND
|
@ AND
|
||||||
|
Loading…
Reference in New Issue
Block a user