1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

Check in a patch that has already been code reviewed by Owen that I'd forgotten to commit.

Build on previous patches to successfully distinguish between an M-series and A/R-series MSR and MRS instruction. These take different mask names and have a *slightly* different opcode format.

Add decoder and disassembler tests.

Improvement on the previous patch - successfully distinguish between valid v6m and v7m masks (one is a subset of the other). The patch had to be edited slightly to apply to ToT.

llvm-svn: 140696
This commit is contained in:
James Molloy 2011-09-28 14:21:38 +00:00
parent 473050b066
commit c4fcff419c
11 changed files with 215 additions and 12 deletions

View File

@ -94,6 +94,10 @@ def FeatureDSPThumb2 : SubtargetFeature<"t2dsp", "Thumb2DSP", "true",
def FeatureMP : SubtargetFeature<"mp", "HasMPExtension", "true",
"Supports Multiprocessing extension">;
// M-series ISA?
def FeatureMClass : SubtargetFeature<"mclass", "IsMClass", "true",
"Is microcontroller profile ('M' series)">;
// ARM ISAs.
def HasV4TOps : SubtargetFeature<"v4t", "HasV4TOps", "true",
"Support ARM v4T instructions">;
@ -185,7 +189,7 @@ def : Processor<"mpcore", ARMV6Itineraries, [HasV6Ops, FeatureVFP2,
// V6M Processors.
def : Processor<"cortex-m0", ARMV6Itineraries, [HasV6Ops, FeatureNoARM,
FeatureDB]>;
FeatureDB, FeatureMClass]>;
// V6T2 Processors.
def : Processor<"arm1156t2-s", ARMV6Itineraries, [HasV6T2Ops,
@ -208,14 +212,14 @@ def : Processor<"cortex-a9-mp", CortexA9Itineraries,
// V7M Processors.
def : ProcNoItin<"cortex-m3", [HasV7Ops,
FeatureThumb2, FeatureNoARM, FeatureDB,
FeatureHWDiv]>;
FeatureHWDiv, FeatureMClass]>;
// V7EM Processors.
def : ProcNoItin<"cortex-m4", [HasV7Ops,
FeatureThumb2, FeatureNoARM, FeatureDB,
FeatureHWDiv, FeatureDSPThumb2,
FeatureT2XtPk, FeatureVFP2,
FeatureVFPOnlySP]>;
FeatureVFPOnlySP, FeatureMClass]>;
//===----------------------------------------------------------------------===//
// Register File Description

View File

@ -205,6 +205,10 @@ def IsThumb : Predicate<"Subtarget->isThumb()">,
def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
def IsThumb2 : Predicate<"Subtarget->isThumb2()">,
AssemblerPredicate<"ModeThumb,FeatureThumb2">;
def IsMClass : Predicate<"Subtarget->isMClass()">,
AssemblerPredicate<"FeatureMClass">;
def IsARClass : Predicate<"!Subtarget->isMClass()">,
AssemblerPredicate<"!FeatureMClass">;
def IsARM : Predicate<"!Subtarget->isThumb()">,
AssemblerPredicate<"!ModeThumb">;
def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;

View File

@ -3540,30 +3540,55 @@ defm t2STC : T2LdStCop<0b1111, 0, "stc">;
// Move between special register and ARM core register -- for disassembly only
//
// Move to ARM core register from Special Register
def t2MRS : T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, apsr", []> {
// A/R class MRS.
//
// A/R class can only move from CPSR or SPSR.
def t2MRS_AR : T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, apsr", []>,
Requires<[IsThumb2,IsARClass]> {
bits<4> Rd;
let Inst{31-12} = 0b11110011111011111000;
let Inst{11-8} = Rd;
let Inst{7-0} = 0b0000;
}
def : t2InstAlias<"mrs${p} $Rd, cpsr", (t2MRS GPR:$Rd, pred:$p)>;
def : t2InstAlias<"mrs${p} $Rd, cpsr", (t2MRS_AR GPR:$Rd, pred:$p)>;
def t2MRSsys:T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr", []> {
def t2MRSsys_AR: T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr", []>,
Requires<[IsThumb2,IsARClass]> {
bits<4> Rd;
let Inst{31-12} = 0b11110011111111111000;
let Inst{11-8} = Rd;
let Inst{7-0} = 0b0000;
}
// M class MRS.
//
// This MRS has a mask field in bits 7-0 and can take more values than
// the A/R class (a full msr_mask).
def t2MRS_M : T2I<(outs rGPR:$Rd), (ins msr_mask:$mask), NoItinerary,
"mrs", "\t$Rd, $mask", []>,
Requires<[IsThumb2,IsMClass]> {
bits<4> Rd;
bits<8> mask;
let Inst{31-12} = 0b11110011111011111000;
let Inst{11-8} = Rd;
let Inst{19-16} = 0b1111;
let Inst{7-0} = mask;
}
// Move from ARM core register to Special Register
//
// A/R class MSR.
//
// No need to have both system and application versions, the encodings are the
// same and the assembly parser has no way to distinguish between them. The mask
// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
// the mask with the fields to be accessed in the special register.
def t2MSR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn),
NoItinerary, "msr", "\t$mask, $Rn", []> {
def t2MSR_AR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn),
NoItinerary, "msr", "\t$mask, $Rn", []>,
Requires<[IsThumb2,IsARClass]> {
bits<5> mask;
bits<4> Rn;
let Inst{31-21} = 0b11110011100;
@ -3574,6 +3599,22 @@ def t2MSR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn),
let Inst{7-0} = 0;
}
// M class MSR.
//
// Move from ARM core register to Special Register
def t2MSR_M : T2I<(outs), (ins msr_mask:$SYSm, rGPR:$Rn),
NoItinerary, "msr", "\t$SYSm, $Rn", []>,
Requires<[IsThumb2,IsMClass]> {
bits<8> SYSm;
bits<4> Rn;
let Inst{31-21} = 0b11110011100;
let Inst{20} = 0b0;
let Inst{19-16} = Rn;
let Inst{15-12} = 0b1000;
let Inst{7-0} = SYSm;
}
//===----------------------------------------------------------------------===//
// Move between coprocessor and ARM core register
//

View File

@ -55,6 +55,7 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
, InThumbMode(false)
, InNaClMode(false)
, HasThumb2(false)
, IsMClass(false)
, NoARM(false)
, PostRAScheduler(false)
, IsR9Reserved(ReserveR9)

View File

@ -76,6 +76,10 @@ protected:
/// HasThumb2 - True if Thumb2 instructions are supported.
bool HasThumb2;
/// IsMClass - True if the subtarget belongs to the 'M' profile of CPUs -
/// v6m, v7m for example.
bool IsMClass;
/// NoARM - True if subtarget does not support ARM mode execution.
bool NoARM;
@ -224,6 +228,8 @@ protected:
bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
bool isThumb2() const { return InThumbMode && HasThumb2; }
bool hasThumb2() const { return HasThumb2; }
bool isMClass() const { return IsMClass; }
bool isARClass() const { return !IsMClass; }
bool isR9Reserved() const { return IsR9Reserved; }

View File

@ -114,10 +114,16 @@ class ARMAsmParser : public MCTargetAsmParser {
bool hasV6Ops() const {
return STI.getFeatureBits() & ARM::HasV6Ops;
}
bool hasV7Ops() const {
return STI.getFeatureBits() & ARM::HasV7Ops;
}
void SwitchMode() {
unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
setAvailableFeatures(FB);
}
bool isMClass() const {
return STI.getFeatureBits() & ARM::FeatureMClass;
}
/// @name Auto-generated Match Functions
/// {
@ -2076,6 +2082,37 @@ parseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
StringRef Mask = Tok.getString();
if (isMClass()) {
// See ARMv6-M 10.1.1
unsigned FlagsVal = StringSwitch<unsigned>(Mask)
.Case("apsr", 0)
.Case("iapsr", 1)
.Case("eapsr", 2)
.Case("xpsr", 3)
.Case("ipsr", 5)
.Case("epsr", 6)
.Case("iepsr", 7)
.Case("msp", 8)
.Case("psp", 9)
.Case("primask", 16)
.Case("basepri", 17)
.Case("basepri_max", 18)
.Case("faultmask", 19)
.Case("control", 20)
.Default(~0U);
if (FlagsVal == ~0U)
return MatchOperand_NoMatch;
if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
// basepri, basepri_max and faultmask only valid for V7m.
return MatchOperand_NoMatch;
Parser.Lex(); // Eat identifier token.
Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
return MatchOperand_Success;
}
// Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
size_t Start = 0, Next = Mask.find('_');
StringRef Flags = "";

View File

@ -621,6 +621,26 @@ void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
unsigned SpecRegRBit = Op.getImm() >> 4;
unsigned Mask = Op.getImm() & 0xf;
if (getAvailableFeatures() & ARM::FeatureMClass) {
switch (Op.getImm()) {
default: assert(0 && "Unexpected mask value!");
case 0: O << "apsr"; return;
case 1: O << "iapsr"; return;
case 2: O << "eapsr"; return;
case 3: O << "xpsr"; return;
case 5: O << "ipsr"; return;
case 6: O << "epsr"; return;
case 7: O << "iepsr"; return;
case 8: O << "msp"; return;
case 9: O << "psp"; return;
case 16: O << "primask"; return;
case 17: O << "basepri"; return;
case 18: O << "basepri_max"; return;
case 19: O << "faultmask"; return;
case 20: O << "control"; return;
}
}
// As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
// APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {

View File

@ -56,18 +56,21 @@ std::string ARM_MC::ParseARMTriple(StringRef TT) {
unsigned SubVer = TT[Idx];
if (SubVer >= '7' && SubVer <= '9') {
if (Len >= Idx+2 && TT[Idx+1] == 'm') {
// v7m: FeatureNoARM, FeatureDB, FeatureHWDiv
ARMArchFeature = "+v7,+noarm,+db,+hwdiv";
// v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass
ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass";
} else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') {
// v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2,
// FeatureT2XtPk
ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk";
// FeatureT2XtPk, FeatureMClass
ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass";
} else
// v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk
ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk";
} else if (SubVer == '6') {
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
ARMArchFeature = "+v6t2";
else if (Len >= Idx+2 && TT[Idx+1] == 'm')
// v6m: FeatureNoARM, FeatureMClass
ARMArchFeature = "+v6t2,+noarm,+mclass";
else
ARMArchFeature = "+v6";
} else if (SubVer == '5') {

View File

@ -0,0 +1,74 @@
@ RUN: llvm-mc -triple=thumbv7m-apple-darwin -show-encoding < %s | FileCheck %s
.syntax unified
.globl _func
@ Check that the assembler can handle the documented syntax from the ARM ARM.
@ These tests test instruction encodings specific to v7m & v7m (FeatureMClass).
@------------------------------------------------------------------------------
@ MRS
@------------------------------------------------------------------------------
mrs r0, apsr
mrs r0, iapsr
mrs r0, eapsr
mrs r0, xpsr
mrs r0, ipsr
mrs r0, epsr
mrs r0, iepsr
mrs r0, msp
mrs r0, psp
mrs r0, primask
mrs r0, basepri
mrs r0, basepri_max
mrs r0, faultmask
mrs r0, control
@ CHECK: mrs r0, apsr @ encoding: [0xef,0xf3,0x00,0x80]
@ CHECK: mrs r0, iapsr @ encoding: [0xef,0xf3,0x01,0x80]
@ CHECK: mrs r0, eapsr @ encoding: [0xef,0xf3,0x02,0x80]
@ CHECK: mrs r0, xpsr @ encoding: [0xef,0xf3,0x03,0x80]
@ CHECK: mrs r0, ipsr @ encoding: [0xef,0xf3,0x05,0x80]
@ CHECK: mrs r0, epsr @ encoding: [0xef,0xf3,0x06,0x80]
@ CHECK: mrs r0, iepsr @ encoding: [0xef,0xf3,0x07,0x80]
@ CHECK: mrs r0, msp @ encoding: [0xef,0xf3,0x08,0x80]
@ CHECK: mrs r0, psp @ encoding: [0xef,0xf3,0x09,0x80]
@ CHECK: mrs r0, primask @ encoding: [0xef,0xf3,0x10,0x80]
@ CHECK: mrs r0, basepri @ encoding: [0xef,0xf3,0x11,0x80]
@ CHECK: mrs r0, basepri_max @ encoding: [0xef,0xf3,0x12,0x80]
@ CHECK: mrs r0, faultmask @ encoding: [0xef,0xf3,0x13,0x80]
@ CHECK: mrs r0, control @ encoding: [0xef,0xf3,0x14,0x80]
@------------------------------------------------------------------------------
@ MSR
@------------------------------------------------------------------------------
msr apsr, r0
msr iapsr, r0
msr eapsr, r0
msr xpsr, r0
msr ipsr, r0
msr epsr, r0
msr iepsr, r0
msr msp, r0
msr psp, r0
msr primask, r0
msr basepri, r0
msr basepri_max, r0
msr faultmask, r0
msr control, r0
@ CHECK: msr apsr, r0 @ encoding: [0x80,0xf3,0x00,0x80]
@ CHECK: msr iapsr, r0 @ encoding: [0x80,0xf3,0x01,0x80]
@ CHECK: msr eapsr, r0 @ encoding: [0x80,0xf3,0x02,0x80]
@ CHECK: msr xpsr, r0 @ encoding: [0x80,0xf3,0x03,0x80]
@ CHECK: msr ipsr, r0 @ encoding: [0x80,0xf3,0x05,0x80]
@ CHECK: msr epsr, r0 @ encoding: [0x80,0xf3,0x06,0x80]
@ CHECK: msr iepsr, r0 @ encoding: [0x80,0xf3,0x07,0x80]
@ CHECK: msr msp, r0 @ encoding: [0x80,0xf3,0x08,0x80]
@ CHECK: msr psp, r0 @ encoding: [0x80,0xf3,0x09,0x80]
@ CHECK: msr primask, r0 @ encoding: [0x80,0xf3,0x10,0x80]
@ CHECK: msr basepri, r0 @ encoding: [0x80,0xf3,0x11,0x80]
@ CHECK: msr basepri_max, r0 @ encoding: [0x80,0xf3,0x12,0x80]
@ CHECK: msr faultmask, r0 @ encoding: [0x80,0xf3,0x13,0x80]
@ CHECK: msr control, r0 @ encoding: [0x80,0xf3,0x14,0x80]

View File

@ -0,0 +1,7 @@
# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 -mcpu cortex-m3 | FileCheck %s
# CHECK: msr primask, r0
0x80 0xf3 0x10 0x80
# CHECK: mrs r0, primask
0xef 0xf3 0x10 0x80

View File

@ -295,3 +295,9 @@
# CHECK: pldw [r11, r12, lsl #2]
0x3b 0xf8 0x2c 0xf0
# CHECK: msr CPSR_fc, r0
0x80 0xf3 0x00 0x89
# CHECK: mrs r0, apsr
0xef 0xf3 0x00 0x80