mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +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;
|
||||
}]>;
|
||||
|
||||
def so_imm_neg :
|
||||
PatLeaf<(imm), [{
|
||||
def so_imm_neg_asmoperand : AsmOperandClass { let Name = "ARMSOImmNeg"; }
|
||||
def so_imm_neg : Operand<i32>, PatLeaf<(imm), [{
|
||||
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
|
||||
// only used on aliases (Pat<> and InstAlias<>). The actual encoding
|
||||
// is handled by the destination instructions, which use t2_so_imm.
|
||||
def so_imm_not_asmoperand : AsmOperandClass { let Name = "ARMSOImmNot"; }
|
||||
def so_imm_not :
|
||||
Operand<i32>, PatLeaf<(imm), [{
|
||||
def so_imm_not : Operand<i32>, PatLeaf<(imm), [{
|
||||
return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
|
||||
}], so_imm_not_XFORM> {
|
||||
let ParserMatchClass = so_imm_not_asmoperand;
|
||||
@ -5041,6 +5042,11 @@ def : MnemonicAlias<"usubaddx", "usax">;
|
||||
// for isel.
|
||||
def : ARMInstAlias<"mov${s}${p} $Rd, $imm",
|
||||
(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,
|
||||
// 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
|
||||
// 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 : Operand<i32>,
|
||||
PatLeaf<(imm), [{
|
||||
def t2_so_imm_not : Operand<i32>, PatLeaf<(imm), [{
|
||||
return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
|
||||
}], t2_so_imm_not_XFORM> {
|
||||
let ParserMatchClass = t2_so_imm_not_asmoperand;
|
||||
}
|
||||
|
||||
// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
|
||||
def t2_so_imm_neg : Operand<i32>,
|
||||
PatLeaf<(imm), [{
|
||||
def t2_so_imm_neg_asmoperand : AsmOperandClass { let Name = "T2SOImmNeg"; }
|
||||
def t2_so_imm_neg : Operand<i32>, PatLeaf<(imm), [{
|
||||
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].
|
||||
def imm0_4095 : Operand<i32>,
|
||||
@ -4096,6 +4097,13 @@ def : t2InstAlias<"sxth${p} $Rd, $Rm$rot",
|
||||
// for isel.
|
||||
def : t2InstAlias<"mov${p} $Rd, $imm",
|
||||
(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.
|
||||
|
@ -749,6 +749,14 @@ public:
|
||||
int64_t Value = CE->getValue();
|
||||
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 {
|
||||
if (Kind != k_Immediate)
|
||||
return false;
|
||||
@ -765,6 +773,14 @@ public:
|
||||
int64_t Value = CE->getValue();
|
||||
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 {
|
||||
if (Kind != k_Immediate)
|
||||
return false;
|
||||
@ -1321,6 +1337,14 @@ public:
|
||||
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 {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
// The operand is actually a so_imm, but we have its bitwise
|
||||
@ -1329,6 +1353,14 @@ public:
|
||||
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 {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
|
||||
|
@ -173,6 +173,9 @@ Lforward:
|
||||
add r6, r7, ror r9
|
||||
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, r6 @ encoding: [0x06,0x40,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 r4, r5, r6, rrx @ encoding: [0x66,0x40,0x85,0xe0]
|
||||
|
||||
|
||||
@ 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, 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 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
|
||||
|
Loading…
Reference in New Issue
Block a user