mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
Add initial support for ARMv7M subtarget and cortex-m3 cpu. Patch by
Jordy <snhjordy@gmail.com>. Followup patches will add some tests and adjust to use Subtarget features for the instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103119 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bc78653057
commit
b1dc393bd5
@ -32,6 +32,8 @@ def ArchV6T2 : SubtargetFeature<"v6t2", "ARMArchVersion", "V6T2",
|
||||
"ARM v6t2">;
|
||||
def ArchV7A : SubtargetFeature<"v7a", "ARMArchVersion", "V7A",
|
||||
"ARM v7A">;
|
||||
def ArchV7M : SubtargetFeature<"v7m", "ARMArchVersion", "V7M",
|
||||
"ARM v7M">;
|
||||
def FeatureVFP2 : SubtargetFeature<"vfp2", "ARMFPUType", "VFPv2",
|
||||
"Enable VFP2 instructions">;
|
||||
def FeatureVFP3 : SubtargetFeature<"vfp3", "ARMFPUType", "VFPv3",
|
||||
@ -126,6 +128,7 @@ def : Processor<"cortex-a8", CortexA8Itineraries,
|
||||
FeatureNEONForFP]>;
|
||||
def : Processor<"cortex-a9", CortexA9Itineraries,
|
||||
[ArchV7A, FeatureThumb2, FeatureNEON]>;
|
||||
def : ProcNoItin<"cortex-m3", [ArchV7M, FeatureThumb2]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Register File Description
|
||||
|
@ -363,8 +363,11 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
|
||||
|
||||
// These are expanded into libcalls.
|
||||
setOperationAction(ISD::SDIV, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UDIV, MVT::i32, Expand);
|
||||
if (!Subtarget->hasV7MOps()) {
|
||||
// v7M has a hardware divider
|
||||
setOperationAction(ISD::SDIV, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UDIV, MVT::i32, Expand);
|
||||
}
|
||||
setOperationAction(ISD::SREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
|
||||
@ -390,7 +393,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
|
||||
setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom);
|
||||
|
||||
if (!Subtarget->hasV6Ops() && !Subtarget->isThumb2()) {
|
||||
if (!Subtarget->hasV6Ops() && !Subtarget->isThumb2() || Subtarget->hasV7MOps()) {
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand);
|
||||
}
|
||||
|
@ -124,6 +124,9 @@ def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
|
||||
def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
|
||||
def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
|
||||
def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
|
||||
def HasV7A : Predicate<"Subtarget->hasV7AOps()">;
|
||||
def HasV7M : Predicate<"Subtarget->hasV7MOps()">;
|
||||
def NoV7M : Predicate<"!Subtarget->hasV7MOps()">;
|
||||
def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
|
||||
def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
|
||||
def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
|
||||
|
@ -639,7 +639,8 @@ multiclass T2I_st<bits<2> opcod, string opc, PatFrag opnode> {
|
||||
multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
|
||||
def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
|
||||
opc, ".w\t$dst, $src",
|
||||
[(set GPR:$dst, (opnode GPR:$src))]> {
|
||||
[(set GPR:$dst, (opnode GPR:$src))]>,
|
||||
Requires<[NoV7M]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0100;
|
||||
let Inst{22-20} = opcod;
|
||||
@ -650,7 +651,8 @@ multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
|
||||
}
|
||||
def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
|
||||
opc, ".w\t$dst, $src, ror $rot",
|
||||
[(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]> {
|
||||
[(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
|
||||
Requires<[NoV7M]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0100;
|
||||
let Inst{22-20} = opcod;
|
||||
@ -665,7 +667,8 @@ multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
|
||||
multiclass T2I_unary_rrot_nw<bits<3> opcod, string opc, PatFrag opnode> {
|
||||
def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
|
||||
opc, "\t$dst, $src",
|
||||
[(set GPR:$dst, (opnode GPR:$src))]> {
|
||||
[(set GPR:$dst, (opnode GPR:$src))]>,
|
||||
Requires<[NoV7M]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0100;
|
||||
let Inst{22-20} = opcod;
|
||||
@ -676,7 +679,8 @@ multiclass T2I_unary_rrot_nw<bits<3> opcod, string opc, PatFrag opnode> {
|
||||
}
|
||||
def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
|
||||
opc, "\t$dst, $src, ror $rot",
|
||||
[(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]> {
|
||||
[(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
|
||||
Requires<[NoV7M]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0100;
|
||||
let Inst{22-20} = opcod;
|
||||
@ -717,7 +721,8 @@ multiclass T2I_unary_rrot_DO<bits<3> opcod, string opc> {
|
||||
multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
|
||||
def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
|
||||
opc, "\t$dst, $LHS, $RHS",
|
||||
[(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]> {
|
||||
[(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
|
||||
Requires<[NoV7M]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0100;
|
||||
let Inst{22-20} = opcod;
|
||||
@ -728,7 +733,8 @@ multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
|
||||
def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
|
||||
IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
|
||||
[(set GPR:$dst, (opnode GPR:$LHS,
|
||||
(rotr GPR:$RHS, rot_imm:$rot)))]> {
|
||||
(rotr GPR:$RHS, rot_imm:$rot)))]>,
|
||||
Requires<[NoV7M]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0100;
|
||||
let Inst{22-20} = opcod;
|
||||
@ -856,9 +862,11 @@ def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
|
||||
let Inst{15} = 0;
|
||||
}
|
||||
|
||||
// Signed and unsigned division, for disassembly only
|
||||
// Signed and unsigned division on v7-M
|
||||
def t2SDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi,
|
||||
"sdiv", "\t$dst, $a, $b", []> {
|
||||
"sdiv", "\t$dst, $a, $b",
|
||||
[(set GPR:$dst, (sdiv GPR:$a, GPR:$b))]>,
|
||||
Requires<[HasV7M]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-21} = 0b011100;
|
||||
let Inst{20} = 0b1;
|
||||
@ -867,7 +875,9 @@ def t2SDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi,
|
||||
}
|
||||
|
||||
def t2UDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi,
|
||||
"udiv", "\t$dst, $a, $b", []> {
|
||||
"udiv", "\t$dst, $a, $b",
|
||||
[(set GPR:$dst, (udiv GPR:$a, GPR:$b))]>,
|
||||
Requires<[HasV7M]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-21} = 0b011101;
|
||||
let Inst{20} = 0b1;
|
||||
@ -2058,7 +2068,8 @@ def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
|
||||
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
|
||||
(and (shl GPR:$src2, (i32 imm:$shamt)),
|
||||
0xFFFF0000)))]> {
|
||||
0xFFFF0000)))]>,
|
||||
Requires<[NoV7M]> {
|
||||
let Inst{31-27} = 0b11101;
|
||||
let Inst{26-25} = 0b01;
|
||||
let Inst{24-20} = 0b01100;
|
||||
@ -2068,15 +2079,18 @@ def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
|
||||
// Alternate cases for PKHBT where identities eliminate some nodes.
|
||||
def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
|
||||
(t2PKHBT GPR:$src1, GPR:$src2, 0)>;
|
||||
(t2PKHBT GPR:$src1, GPR:$src2, 0)>,
|
||||
Requires<[NoV7M]>;
|
||||
def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
|
||||
(t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
|
||||
(t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>,
|
||||
Requires<[NoV7M]>;
|
||||
|
||||
def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
|
||||
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
|
||||
(and (sra GPR:$src2, imm16_31:$shamt),
|
||||
0xFFFF)))]> {
|
||||
0xFFFF)))]>,
|
||||
Requires<[NoV7M]> {
|
||||
let Inst{31-27} = 0b11101;
|
||||
let Inst{26-25} = 0b01;
|
||||
let Inst{24-20} = 0b01100;
|
||||
@ -2087,10 +2101,12 @@ def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
// Alternate cases for PKHTB where identities eliminate some nodes. Note that
|
||||
// a shift amount of 0 is *not legal* here, it is PKHBT instead.
|
||||
def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
|
||||
(t2PKHTB GPR:$src1, GPR:$src2, 16)>;
|
||||
(t2PKHTB GPR:$src1, GPR:$src2, 16)>,
|
||||
Requires<[NoV7M]>;
|
||||
def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
|
||||
(and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
|
||||
(t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
|
||||
(t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>,
|
||||
Requires<[NoV7M]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Comparison Instructions...
|
||||
|
@ -73,6 +73,8 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
|
||||
unsigned SubVer = TT[Idx];
|
||||
if (SubVer >= '7' && SubVer <= '9') {
|
||||
ARMArchVersion = V7A;
|
||||
if (Len >= Idx+2 && TT[Idx+1] == 'm')
|
||||
ARMArchVersion = V7M;
|
||||
} else if (SubVer == '6') {
|
||||
ARMArchVersion = V6;
|
||||
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
|
||||
|
@ -26,7 +26,7 @@ class GlobalValue;
|
||||
class ARMSubtarget : public TargetSubtarget {
|
||||
protected:
|
||||
enum ARMArchEnum {
|
||||
V4, V4T, V5T, V5TE, V6, V6T2, V7A
|
||||
V4, V4T, V5T, V5TE, V6, V6T2, V7A, V7M
|
||||
};
|
||||
|
||||
enum ARMFPEnum {
|
||||
@ -39,7 +39,7 @@ protected:
|
||||
};
|
||||
|
||||
/// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE,
|
||||
/// V6, V6T2, V7A.
|
||||
/// V6, V6T2, V7A, V7M.
|
||||
ARMArchEnum ARMArchVersion;
|
||||
|
||||
/// ARMFPUType - Floating Point Unit type.
|
||||
@ -117,6 +117,8 @@ protected:
|
||||
bool hasV6Ops() const { return ARMArchVersion >= V6; }
|
||||
bool hasV6T2Ops() const { return ARMArchVersion >= V6T2; }
|
||||
bool hasV7Ops() const { return ARMArchVersion >= V7A; }
|
||||
bool hasV7AOps() const { return ARMArchVersion == V7A; }
|
||||
bool hasV7MOps() const { return ARMArchVersion == V7M; }
|
||||
|
||||
bool hasVFP2() const { return ARMFPUType >= VFPv2; }
|
||||
bool hasVFP3() const { return ARMFPUType >= VFPv3; }
|
||||
|
Loading…
Reference in New Issue
Block a user