mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-19 06:31:18 +00:00
[ARM64] Move register/register MOV handling into tablegen and improve diagnostics
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208527 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e7dd13a094
commit
0d919c62c4
@ -430,8 +430,14 @@ def logical_imm64_XFORM : SDNodeXForm<imm, [{
|
|||||||
return CurDAG->getTargetConstant(enc, MVT::i32);
|
return CurDAG->getTargetConstant(enc, MVT::i32);
|
||||||
}]>;
|
}]>;
|
||||||
|
|
||||||
def LogicalImm32Operand : AsmOperandClass { let Name = "LogicalImm32"; }
|
def LogicalImm32Operand : AsmOperandClass {
|
||||||
def LogicalImm64Operand : AsmOperandClass { let Name = "LogicalImm64"; }
|
let Name = "LogicalImm32";
|
||||||
|
let DiagnosticType = "LogicalSecondSource";
|
||||||
|
}
|
||||||
|
def LogicalImm64Operand : AsmOperandClass {
|
||||||
|
let Name = "LogicalImm64";
|
||||||
|
let DiagnosticType = "LogicalSecondSource";
|
||||||
|
}
|
||||||
def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
|
def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
|
||||||
return ARM64_AM::isLogicalImmediate(N->getZExtValue(), 32);
|
return ARM64_AM::isLogicalImmediate(N->getZExtValue(), 32);
|
||||||
}], logical_imm32_XFORM> {
|
}], logical_imm32_XFORM> {
|
||||||
|
@ -474,6 +474,15 @@ def : InstAlias<"ngcs $dst, $src", (SBCSXr GPR64:$dst, XZR, GPR64:$src)>;
|
|||||||
defm ADD : AddSub<0, "add", add>;
|
defm ADD : AddSub<0, "add", add>;
|
||||||
defm SUB : AddSub<1, "sub">;
|
defm SUB : AddSub<1, "sub">;
|
||||||
|
|
||||||
|
def : InstAlias<"mov $dst, $src",
|
||||||
|
(ADDWri GPR32sponly:$dst, GPR32sp:$src, 0, 0)>;
|
||||||
|
def : InstAlias<"mov $dst, $src",
|
||||||
|
(ADDWri GPR32sp:$dst, GPR32sponly:$src, 0, 0)>;
|
||||||
|
def : InstAlias<"mov $dst, $src",
|
||||||
|
(ADDXri GPR64sponly:$dst, GPR64sp:$src, 0, 0)>;
|
||||||
|
def : InstAlias<"mov $dst, $src",
|
||||||
|
(ADDXri GPR64sp:$dst, GPR64sponly:$src, 0, 0)>;
|
||||||
|
|
||||||
defm ADDS : AddSubS<0, "adds", ARM64add_flag, "cmn">;
|
defm ADDS : AddSubS<0, "adds", ARM64add_flag, "cmn">;
|
||||||
defm SUBS : AddSubS<1, "subs", ARM64sub_flag, "cmp">;
|
defm SUBS : AddSubS<1, "subs", ARM64sub_flag, "cmp">;
|
||||||
|
|
||||||
@ -648,6 +657,9 @@ defm ORN : LogicalReg<0b01, 1, "orn",
|
|||||||
BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
|
BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
|
||||||
defm ORR : LogicalReg<0b01, 0, "orr", or>;
|
defm ORR : LogicalReg<0b01, 0, "orr", or>;
|
||||||
|
|
||||||
|
def : InstAlias<"mov $dst, $src", (ORRWrs GPR32:$dst, WZR, GPR32:$src, 0)>;
|
||||||
|
def : InstAlias<"mov $dst, $src", (ORRXrs GPR64:$dst, XZR, GPR64:$src, 0)>;
|
||||||
|
|
||||||
def : InstAlias<"tst $src1, $src2",
|
def : InstAlias<"tst $src1, $src2",
|
||||||
(ANDSWri WZR, GPR32:$src1, logical_imm32:$src2)>;
|
(ANDSWri WZR, GPR32:$src1, logical_imm32:$src2)>;
|
||||||
def : InstAlias<"tst $src1, $src2",
|
def : InstAlias<"tst $src1, $src2",
|
||||||
|
@ -152,6 +152,9 @@ def GPR64sp : RegisterClass<"ARM64", [i64], 64, (add GPR64common, SP)> {
|
|||||||
let AltOrderSelect = [{ return 1; }];
|
let AltOrderSelect = [{ return 1; }];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def GPR32sponly : RegisterClass<"ARM64", [i32], 32, (add WSP)>;
|
||||||
|
def GPR64sponly : RegisterClass<"ARM64", [i64], 64, (add SP)>;
|
||||||
|
|
||||||
// GPR register classes which include WZR/XZR AND SP/WSP. This is not a
|
// GPR register classes which include WZR/XZR AND SP/WSP. This is not a
|
||||||
// constraint used by any instructions, it is used as a common super-class.
|
// constraint used by any instructions, it is used as a common super-class.
|
||||||
def GPR32all : RegisterClass<"ARM64", [i32], 32, (add GPR32common, WZR, WSP)>;
|
def GPR32all : RegisterClass<"ARM64", [i32], 32, (add GPR32common, WZR, WSP)>;
|
||||||
|
@ -3945,42 +3945,6 @@ static void rewriteMOVI(ARM64AsmParser::OperandVector &Operands,
|
|||||||
delete Op;
|
delete Op;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rewriteMOVRSP(ARM64AsmParser::OperandVector &Operands,
|
|
||||||
MCContext &Context) {
|
|
||||||
ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
|
|
||||||
ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
|
|
||||||
Operands[0] =
|
|
||||||
ARM64Operand::CreateToken("add", false, Op->getStartLoc(), Context);
|
|
||||||
|
|
||||||
const MCExpr *Imm = MCConstantExpr::Create(0, Context);
|
|
||||||
Operands.push_back(ARM64Operand::CreateShiftedImm(Imm, 0, Op2->getStartLoc(),
|
|
||||||
Op2->getEndLoc(), Context));
|
|
||||||
|
|
||||||
delete Op;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rewriteMOVR(ARM64AsmParser::OperandVector &Operands,
|
|
||||||
MCContext &Context) {
|
|
||||||
ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
|
|
||||||
ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
|
|
||||||
Operands[0] =
|
|
||||||
ARM64Operand::CreateToken("orr", false, Op->getStartLoc(), Context);
|
|
||||||
|
|
||||||
// Operands[2] becomes Operands[3].
|
|
||||||
Operands.push_back(Operands[2]);
|
|
||||||
// And Operands[2] becomes ZR.
|
|
||||||
unsigned ZeroReg = ARM64::XZR;
|
|
||||||
if (ARM64MCRegisterClasses[ARM64::GPR32allRegClassID].contains(
|
|
||||||
Operands[2]->getReg()))
|
|
||||||
ZeroReg = ARM64::WZR;
|
|
||||||
|
|
||||||
Operands[2] =
|
|
||||||
ARM64Operand::CreateReg(ZeroReg, false, Op2->getStartLoc(),
|
|
||||||
Op2->getEndLoc(), Context);
|
|
||||||
|
|
||||||
delete Op;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
|
bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
|
||||||
switch (ErrCode) {
|
switch (ErrCode) {
|
||||||
case Match_MissingFeature:
|
case Match_MissingFeature:
|
||||||
@ -3999,6 +3963,8 @@ bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
|
|||||||
case Match_AddSubSecondSource:
|
case Match_AddSubSecondSource:
|
||||||
return Error(Loc,
|
return Error(Loc,
|
||||||
"expected compatible register, symbol or integer in range [0, 4095]");
|
"expected compatible register, symbol or integer in range [0, 4095]");
|
||||||
|
case Match_LogicalSecondSource:
|
||||||
|
return Error(Loc, "expected compatible register or logical immediate");
|
||||||
case Match_AddSubRegShift32:
|
case Match_AddSubRegShift32:
|
||||||
return Error(Loc,
|
return Error(Loc,
|
||||||
"expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
|
"expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
|
||||||
@ -4081,7 +4047,6 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||||||
// FIXME: Catching this here is a total hack, and we should use tblgen
|
// FIXME: Catching this here is a total hack, and we should use tblgen
|
||||||
// support to implement this instead as soon as it is available.
|
// support to implement this instead as soon as it is available.
|
||||||
|
|
||||||
ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
|
|
||||||
ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
|
ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
|
||||||
if (Op2->isImm()) {
|
if (Op2->isImm()) {
|
||||||
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op2->getImm())) {
|
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op2->getImm())) {
|
||||||
@ -4130,21 +4095,6 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||||||
else if ((NVal & 0xFFFF000000000000ULL) == NVal)
|
else if ((NVal & 0xFFFF000000000000ULL) == NVal)
|
||||||
rewriteMOVI(Operands, "movn", NVal, 48, getContext());
|
rewriteMOVI(Operands, "movn", NVal, 48, getContext());
|
||||||
}
|
}
|
||||||
} else if (Op1->isReg() && Op2->isReg()) {
|
|
||||||
// reg->reg move.
|
|
||||||
unsigned Reg1 = Op1->getReg();
|
|
||||||
unsigned Reg2 = Op2->getReg();
|
|
||||||
if ((Reg1 == ARM64::SP &&
|
|
||||||
ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains(Reg2)) ||
|
|
||||||
(Reg2 == ARM64::SP &&
|
|
||||||
ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains(Reg1)) ||
|
|
||||||
(Reg1 == ARM64::WSP &&
|
|
||||||
ARM64MCRegisterClasses[ARM64::GPR32allRegClassID].contains(Reg2)) ||
|
|
||||||
(Reg2 == ARM64::WSP &&
|
|
||||||
ARM64MCRegisterClasses[ARM64::GPR32allRegClassID].contains(Reg1)))
|
|
||||||
rewriteMOVRSP(Operands, getContext());
|
|
||||||
else
|
|
||||||
rewriteMOVR(Operands, getContext());
|
|
||||||
}
|
}
|
||||||
} else if (NumOperands == 4) {
|
} else if (NumOperands == 4) {
|
||||||
if (NumOperands == 4 && Tok == "lsl") {
|
if (NumOperands == 4 && Tok == "lsl") {
|
||||||
@ -4523,6 +4473,7 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||||||
case Match_AddSubRegExtendSmall:
|
case Match_AddSubRegExtendSmall:
|
||||||
case Match_AddSubRegExtendLarge:
|
case Match_AddSubRegExtendLarge:
|
||||||
case Match_AddSubSecondSource:
|
case Match_AddSubSecondSource:
|
||||||
|
case Match_LogicalSecondSource:
|
||||||
case Match_AddSubRegShift32:
|
case Match_AddSubRegShift32:
|
||||||
case Match_AddSubRegShift64:
|
case Match_AddSubRegShift64:
|
||||||
case Match_InvalidMemoryIndexed8:
|
case Match_InvalidMemoryIndexed8:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user