mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
[ARM] Introduce the 'sevl' instruction in ARMv8.
This also removes the restriction on the immediate field of the 'hint' instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191744 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9813dbf396
commit
d1311ac171
@ -112,6 +112,10 @@ def int_arm_crc32w : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
|
||||
def int_arm_crc32cw : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// HINT
|
||||
def int_arm_sevl : Intrinsic<[], []>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Advanced SIMD (NEON)
|
||||
|
||||
|
@ -594,17 +594,6 @@ def imm0_1 : Operand<i32> { let ParserMatchClass = Imm0_1AsmOperand; }
|
||||
def Imm0_3AsmOperand: ImmAsmOperand { let Name = "Imm0_3"; }
|
||||
def imm0_3 : Operand<i32> { let ParserMatchClass = Imm0_3AsmOperand; }
|
||||
|
||||
/// imm0_4 predicate - Immediate in the range [0,4].
|
||||
def Imm0_4AsmOperand : ImmAsmOperand
|
||||
{
|
||||
let Name = "Imm0_4";
|
||||
let DiagnosticType = "ImmRange0_4";
|
||||
}
|
||||
def imm0_4 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 5; }]> {
|
||||
let ParserMatchClass = Imm0_4AsmOperand;
|
||||
let DecoderMethod = "DecodeImm0_4";
|
||||
}
|
||||
|
||||
/// imm0_7 predicate - Immediate in the range [0,7].
|
||||
def Imm0_7AsmOperand: ImmAsmOperand { let Name = "Imm0_7"; }
|
||||
def imm0_7 : Operand<i32>, ImmLeaf<i32, [{
|
||||
@ -1677,11 +1666,11 @@ PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
|
||||
[(ARMcallseq_start timm:$amt)]>;
|
||||
}
|
||||
|
||||
def HINT : AI<(outs), (ins imm0_4:$imm), MiscFrm, NoItinerary,
|
||||
def HINT : AI<(outs), (ins imm0_255:$imm), MiscFrm, NoItinerary,
|
||||
"hint", "\t$imm", []>, Requires<[IsARM, HasV6]> {
|
||||
bits<3> imm;
|
||||
let Inst{27-3} = 0b0011001000001111000000000;
|
||||
let Inst{2-0} = imm;
|
||||
bits<8> imm;
|
||||
let Inst{27-8} = 0b00110010000011110000;
|
||||
let Inst{7-0} = imm;
|
||||
}
|
||||
|
||||
def : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6T2]>;
|
||||
@ -1689,6 +1678,9 @@ def : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6T2]>;
|
||||
def : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6T2]>;
|
||||
def : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6T2]>;
|
||||
def : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6T2]>;
|
||||
def : InstAlias<"sevl$p", (HINT 5, pred:$p)>, Requires<[IsARM, HasV8]>;
|
||||
|
||||
def : Pat<(int_arm_sevl), (HINT 5)>;
|
||||
|
||||
def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel",
|
||||
"\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> {
|
||||
|
@ -289,6 +289,11 @@ def tSEV : T1pI<(outs), (ins), NoItinerary, "sev", "", []>,
|
||||
T1SystemEncoding<0x40>, // A8.6.157
|
||||
Requires<[IsThumb2]>;
|
||||
|
||||
def tSEVL : T1pI<(outs), (ins), NoItinerary, "sevl", "", [(int_arm_sevl)]>,
|
||||
T1SystemEncoding<0x50>,
|
||||
Requires<[IsThumb2, HasV8]>;
|
||||
|
||||
|
||||
// The imm operand $val can be used by a debugger to store more information
|
||||
// about the breakpoint.
|
||||
def tBKPT : T1I<(outs), (ins imm0_255:$val), NoItinerary, "bkpt\t$val",
|
||||
|
@ -3652,18 +3652,21 @@ def : t2InstAlias<"cps.w $mode", (t2CPS1p imm0_31:$mode), 0>;
|
||||
|
||||
// A6.3.4 Branches and miscellaneous control
|
||||
// Table A6-14 Change Processor State, and hint instructions
|
||||
def t2HINT : T2I<(outs), (ins imm0_4:$imm), NoItinerary, "hint", "\t$imm",[]> {
|
||||
def t2HINT : T2I<(outs), (ins imm0_255:$imm), NoItinerary, "hint", "\t$imm",[]> {
|
||||
bits<3> imm;
|
||||
let Inst{31-3} = 0b11110011101011111000000000000;
|
||||
let Inst{2-0} = imm;
|
||||
}
|
||||
|
||||
def : t2InstAlias<"hint$p.w $imm", (t2HINT imm0_4:$imm, pred:$p)>;
|
||||
def : t2InstAlias<"hint$p.w $imm", (t2HINT imm0_255:$imm, pred:$p)>;
|
||||
def : t2InstAlias<"nop$p.w", (t2HINT 0, pred:$p)>;
|
||||
def : t2InstAlias<"yield$p.w", (t2HINT 1, pred:$p)>;
|
||||
def : t2InstAlias<"wfe$p.w", (t2HINT 2, pred:$p)>;
|
||||
def : t2InstAlias<"wfi$p.w", (t2HINT 3, pred:$p)>;
|
||||
def : t2InstAlias<"sev$p.w", (t2HINT 4, pred:$p)>;
|
||||
def : t2InstAlias<"sevl$p.w", (t2HINT 5, pred:$p)> {
|
||||
let Predicates = [IsThumb2, HasV8];
|
||||
}
|
||||
|
||||
def t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt", []> {
|
||||
bits<4> opt;
|
||||
|
@ -679,13 +679,6 @@ public:
|
||||
int64_t Value = CE->getValue();
|
||||
return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
|
||||
}
|
||||
bool isImm0_4() const {
|
||||
if (!isImm()) return false;
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
|
||||
if (!CE) return false;
|
||||
int64_t Value = CE->getValue();
|
||||
return Value >= 0 && Value < 5;
|
||||
}
|
||||
bool isImm0_1020s4() const {
|
||||
if (!isImm()) return false;
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
|
||||
@ -7687,11 +7680,6 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
return Error(IDLoc, "instruction variant requires ARMv6 or later");
|
||||
case Match_RequiresThumb2:
|
||||
return Error(IDLoc, "instruction variant requires Thumb2");
|
||||
case Match_ImmRange0_4: {
|
||||
SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
|
||||
if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
|
||||
return Error(ErrorLoc, "immediate operand must be in the range [0,4]");
|
||||
}
|
||||
case Match_ImmRange0_15: {
|
||||
SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
|
||||
if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
|
||||
|
@ -84,6 +84,11 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
||||
case 2: O << "\twfe"; break;
|
||||
case 3: O << "\twfi"; break;
|
||||
case 4: O << "\tsev"; break;
|
||||
case 5:
|
||||
if ((getAvailableFeatures() & ARM::HasV8Ops)) {
|
||||
O << "\tsevl";
|
||||
break;
|
||||
} // Fallthrough for non-v8
|
||||
default:
|
||||
// Anything else should just print normally.
|
||||
printInstruction(MI, O);
|
||||
|
@ -9,8 +9,11 @@ define void @test() {
|
||||
call void @llvm.arm.dsb(i32 15)
|
||||
; CHECK: dsb ishld
|
||||
call void @llvm.arm.dsb(i32 9)
|
||||
; CHECK: sevl
|
||||
tail call void @llvm.arm.sevl() nounwind
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.arm.dmb(i32)
|
||||
declare void @llvm.arm.dsb(i32)
|
||||
declare void @llvm.arm.sevl() nounwind
|
||||
|
@ -50,3 +50,10 @@
|
||||
@ CHECK-V7: error: invalid operand for instruction
|
||||
@ CHECK-V7: error: invalid operand for instruction
|
||||
@ CHECK-V7: error: invalid operand for instruction
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SEVL
|
||||
@------------------------------------------------------------------------------
|
||||
sevl
|
||||
|
||||
@ CHECK: sevl @ encoding: [0x05,0xf0,0x20,0xe3]
|
||||
|
@ -2928,6 +2928,7 @@ Lforward:
|
||||
hint #2
|
||||
hint #1
|
||||
hint #0
|
||||
hint #255
|
||||
|
||||
@ CHECK: wfe @ encoding: [0x02,0xf0,0x20,0xe3]
|
||||
@ CHECK: wfehi @ encoding: [0x02,0xf0,0x20,0x83]
|
||||
@ -2940,3 +2941,4 @@ Lforward:
|
||||
@ CHECK: wfe @ encoding: [0x02,0xf0,0x20,0xe3]
|
||||
@ CHECK: yield @ encoding: [0x01,0xf0,0x20,0xe3]
|
||||
@ CHECK: nop @ encoding: [0x00,0xf0,0x20,0xe3]
|
||||
@ CHECK: hint #255 @ encoding: [0xff,0xf0,0x20,0xe3]
|
||||
|
@ -69,3 +69,16 @@
|
||||
@ CHECK-V7: error: invalid operand for instruction
|
||||
@ CHECK-V7: error: invalid operand for instruction
|
||||
@ CHECK-V7: error: invalid operand for instruction
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SEVL
|
||||
@------------------------------------------------------------------------------
|
||||
sevl
|
||||
sevl.w
|
||||
it ge
|
||||
sevlge
|
||||
|
||||
@ CHECK-V8: sevl @ encoding: [0x50,0xbf]
|
||||
@ CHECK-V8: sevl.w @ encoding: [0xaf,0xf3,0x05,0x80]
|
||||
@ CHECK-V8: it ge @ encoding: [0xa8,0xbf]
|
||||
@ CHECK-V8: sevlge @ encoding: [0x50,0xbf]
|
||||
|
@ -1,7 +0,0 @@
|
||||
@ RUN: not llvm-mc -triple=armv7-apple-darwin -mcpu=cortex-a8 < %s 2>&1 | FileCheck %s
|
||||
|
||||
hint #5
|
||||
hint #100
|
||||
|
||||
@ CHECK: error: immediate operand must be in the range [0,4]
|
||||
@ CHECK: error: immediate operand must be in the range [0,4]
|
@ -1,9 +0,0 @@
|
||||
@ RUN: not llvm-mc -triple=thumbv7-apple-darwin -mcpu=cortex-a8 < %s 2>&1 | FileCheck %s
|
||||
|
||||
hint #5
|
||||
hint.w #5
|
||||
hint #100
|
||||
|
||||
@ CHECK: error: immediate operand must be in the range [0,4]
|
||||
@ CHECK: error: immediate operand must be in the range [0,4]
|
||||
@ CHECK: error: immediate operand must be in the range [0,4]
|
@ -18,3 +18,6 @@
|
||||
# CHECK: dmb oshld
|
||||
# CHECK: dmb nshld
|
||||
# CHECK: dmb ld
|
||||
|
||||
0x05 0xf0 0x20 0xe3
|
||||
# CHECK: sevl
|
||||
|
@ -2420,6 +2420,7 @@
|
||||
# CHECK: wfilt
|
||||
# CHECK: yield
|
||||
# CHECK: yieldne
|
||||
# CHECK: hint #5
|
||||
|
||||
0x02 0xf0 0x20 0xe3
|
||||
0x02 0xf0 0x20 0x83
|
||||
@ -2427,3 +2428,4 @@
|
||||
0x03 0xf0 0x20 0xb3
|
||||
0x01 0xf0 0x20 0xe3
|
||||
0x01 0xf0 0x20 0x13
|
||||
0x05 0xf0 0x20 0xe3
|
||||
|
@ -69,14 +69,6 @@
|
||||
# Undefined encoding space for hint instructions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
[0x05 0xf0 0x20 0xe3]
|
||||
# CHECK: invalid instruction encoding
|
||||
# CHECK-NEXT: [0x05 0xf0 0x20 0xe3]
|
||||
|
||||
[0x41 0xf0 0x20 0xe3]
|
||||
# CHECK: invalid instruction encoding
|
||||
# CHECK-NEXT: [0x41 0xf0 0x20 0xe3]
|
||||
|
||||
# FIXME: is it "dbg #14" or not????
|
||||
[0xfe 0xf0 0x20 0xe3]
|
||||
# CHCK: invalid instruction encoding
|
||||
|
@ -37,10 +37,9 @@
|
||||
# Undefined encoding space for hint instructions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
[0xaf 0xf3 0x05 0x80]
|
||||
[0x60 0xbf]
|
||||
# CHECK: invalid instruction encoding
|
||||
# CHECK-NEXT: [0xaf 0xf3 0x05 0x80]
|
||||
|
||||
# CHECK-NEXT: [0x60 0xbf]
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Undefined encoding for it
|
||||
|
Loading…
x
Reference in New Issue
Block a user