forked from OSchip/llvm-project
[RISCV] AsmParser support for the li pseudo instruction
The implementation follows the MIPS backend and expands the pseudo instruction directly during asm parsing. As the result, only real MC instructions are emitted to the MCStreamer. The actual expansion to real instructions is similar to the expansion performed by the GNU Assembler. This patch supersedes D41949. Differential Revision: https://reviews.llvm.org/D46118 Patch by Mario Werner. llvm-svn: 334203
This commit is contained in:
parent
6cfb31c7c1
commit
6a4b5441e4
|
@ -16,6 +16,7 @@
|
|||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstBuilder.h"
|
||||
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
|
||||
|
@ -23,8 +24,11 @@
|
|||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// Include the auto-generated portion of the compress emitter.
|
||||
|
@ -47,7 +51,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
|
|||
unsigned Kind) override;
|
||||
|
||||
bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
|
||||
int Lower, int Upper, Twine Msg);
|
||||
int64_t Lower, int64_t Upper, Twine Msg);
|
||||
|
||||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
|
@ -61,6 +65,20 @@ class RISCVAsmParser : public MCTargetAsmParser {
|
|||
|
||||
bool ParseDirective(AsmToken DirectiveID) override;
|
||||
|
||||
// Helper to actually emit an instruction to the MCStreamer. Also, when
|
||||
// possible, compression of the instruction is performed.
|
||||
void emitToStreamer(MCStreamer &S, const MCInst &Inst);
|
||||
|
||||
// Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
|
||||
// synthesize the desired immedate value into the destination register.
|
||||
void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out);
|
||||
|
||||
/// Helper for processing MC instructions that have been successfully matched
|
||||
/// by MatchAndEmitInstruction. Modifications to the emitted instructions,
|
||||
/// like the expansion of pseudo instructions (e.g., "li"), can be performed
|
||||
/// in this method.
|
||||
bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
|
||||
|
||||
// Auto-generated instruction matching functions
|
||||
#define GET_ASSEMBLER_HEADER
|
||||
#include "RISCVGenAsmMatcher.inc"
|
||||
|
@ -247,6 +265,18 @@ public:
|
|||
return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
|
||||
}
|
||||
|
||||
bool isImmXLen() const {
|
||||
int64_t Imm;
|
||||
RISCVMCExpr::VariantKind VK;
|
||||
if (!isImm())
|
||||
return false;
|
||||
bool IsConstantImm = evaluateConstantImm(Imm, VK);
|
||||
// Given only Imm, ensuring that the actually specified constant is either
|
||||
// a signed or unsigned 64-bit number is unfortunately impossible.
|
||||
bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm);
|
||||
return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None;
|
||||
}
|
||||
|
||||
bool isUImmLog2XLen() const {
|
||||
int64_t Imm;
|
||||
RISCVMCExpr::VariantKind VK;
|
||||
|
@ -620,7 +650,7 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
|
|||
}
|
||||
|
||||
bool RISCVAsmParser::generateImmOutOfRangeError(
|
||||
OperandVector &Operands, uint64_t ErrorInfo, int Lower, int Upper,
|
||||
OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
|
||||
Twine Msg = "immediate must be an integer in the range") {
|
||||
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
|
||||
|
@ -636,14 +666,8 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
|
||||
default:
|
||||
break;
|
||||
case Match_Success: {
|
||||
MCInst CInst;
|
||||
bool Res = compressInst(CInst, Inst, getSTI(), Out.getContext());
|
||||
CInst.setLoc(IDLoc);
|
||||
Inst.setLoc(IDLoc);
|
||||
Out.EmitInstruction((Res ? CInst : Inst), getSTI());
|
||||
return false;
|
||||
}
|
||||
case Match_Success:
|
||||
return processInstruction(Inst, IDLoc, Out);
|
||||
case Match_MissingFeature:
|
||||
return Error(IDLoc, "instruction use requires an option to be enabled");
|
||||
case Match_MnemonicFail:
|
||||
|
@ -660,6 +684,14 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
}
|
||||
return Error(ErrorLoc, "invalid operand for instruction");
|
||||
}
|
||||
case Match_InvalidImmXLen:
|
||||
if (isRV64()) {
|
||||
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
return Error(ErrorLoc, "operand must be a constant 64-bit integer");
|
||||
}
|
||||
return generateImmOutOfRangeError(Operands, ErrorInfo,
|
||||
std::numeric_limits<int32_t>::min(),
|
||||
std::numeric_limits<uint32_t>::max());
|
||||
case Match_InvalidUImmLog2XLen:
|
||||
if (isRV64())
|
||||
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
|
||||
|
@ -1067,6 +1099,111 @@ bool RISCVAsmParser::parseDirectiveOption() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
|
||||
MCInst CInst;
|
||||
bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
|
||||
CInst.setLoc(Inst.getLoc());
|
||||
S.EmitInstruction((Res ? CInst : Inst), getSTI());
|
||||
}
|
||||
|
||||
void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value,
|
||||
MCStreamer &Out) {
|
||||
if (isInt<32>(Value)) {
|
||||
// Emits the MC instructions for loading a 32-bit constant into a register.
|
||||
//
|
||||
// Depending on the active bits in the immediate Value v, the following
|
||||
// instruction sequences are emitted:
|
||||
//
|
||||
// v == 0 : ADDI(W)
|
||||
// v[0,12) != 0 && v[12,32) == 0 : ADDI(W)
|
||||
// v[0,12) == 0 && v[12,32) != 0 : LUI
|
||||
// v[0,32) != 0 : LUI+ADDI(W)
|
||||
//
|
||||
int64_t Hi20 = ((Value + 0x800) >> 12) & 0xFFFFF;
|
||||
int64_t Lo12 = SignExtend64<12>(Value);
|
||||
unsigned SrcReg = RISCV::X0;
|
||||
|
||||
if (Hi20) {
|
||||
emitToStreamer(Out,
|
||||
MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Hi20));
|
||||
SrcReg = DestReg;
|
||||
}
|
||||
|
||||
if (Lo12 || Hi20 == 0) {
|
||||
unsigned AddiOpcode =
|
||||
STI->hasFeature(RISCV::Feature64Bit) ? RISCV::ADDIW : RISCV::ADDI;
|
||||
emitToStreamer(Out, MCInstBuilder(AddiOpcode)
|
||||
.addReg(DestReg)
|
||||
.addReg(SrcReg)
|
||||
.addImm(Lo12));
|
||||
}
|
||||
return;
|
||||
}
|
||||
assert(STI->hasFeature(RISCV::Feature64Bit) &&
|
||||
"Target must be 64-bit to support a >32-bit constant");
|
||||
|
||||
// In the worst case, for a full 64-bit constant, a sequence of 8 instructions
|
||||
// (i.e., LUI+ADDIW+SLLI+ADDI+SLLI+ADDI+SLLI+ADDI) has to be emmitted. Note
|
||||
// that the first two instructions (LUI+ADDIW) can contribute up to 32 bits
|
||||
// while the following ADDI instructions contribute up to 12 bits each.
|
||||
//
|
||||
// On the first glance, implementing this seems to be possible by simply
|
||||
// emitting the most significant 32 bits (LUI+ADDIW) followed by as many left
|
||||
// shift (SLLI) and immediate additions (ADDI) as needed. However, due to the
|
||||
// fact that ADDI performs a sign extended addition, doing it like that would
|
||||
// only be possible when at most 11 bits of the ADDI instructions are used.
|
||||
// Using all 12 bits of the ADDI instructions, like done by GAS, actually
|
||||
// requires that the constant is processed starting with the least significant
|
||||
// bit.
|
||||
//
|
||||
// In the following, constants are processed from LSB to MSB but instruction
|
||||
// emission is performed from MSB to LSB by recursively calling
|
||||
// emitLoadImm. In each recursion, first the lowest 12 bits are removed
|
||||
// from the constant and the optimal shift amount, which can be greater than
|
||||
// 12 bits if the constant is sparse, is determined. Then, the shifted
|
||||
// remaining constant is processed recursively and gets emitted as soon as it
|
||||
// fits into 32 bits. The emission of the shifts and additions is subsequently
|
||||
// performed when the recursion returns.
|
||||
//
|
||||
int64_t Lo12 = SignExtend64<12>(Value);
|
||||
int64_t Hi52 = (Value + 0x800) >> 12;
|
||||
int ShiftAmount = 12 + findFirstSet((uint64_t)Hi52);
|
||||
Hi52 = SignExtend64(Hi52 >> (ShiftAmount - 12), 64 - ShiftAmount);
|
||||
|
||||
emitLoadImm(DestReg, Hi52, Out);
|
||||
|
||||
emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
|
||||
.addReg(DestReg)
|
||||
.addReg(DestReg)
|
||||
.addImm(ShiftAmount));
|
||||
|
||||
if (Lo12)
|
||||
emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
|
||||
.addReg(DestReg)
|
||||
.addReg(DestReg)
|
||||
.addImm(Lo12));
|
||||
}
|
||||
|
||||
bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
||||
MCStreamer &Out) {
|
||||
Inst.setLoc(IDLoc);
|
||||
|
||||
if (Inst.getOpcode() == RISCV::PseudoLI) {
|
||||
auto Reg = Inst.getOperand(0).getReg();
|
||||
int64_t Imm = Inst.getOperand(1).getImm();
|
||||
// On RV32 the immediate here can either be a signed or an unsigned
|
||||
// 32-bit number. Sign extension has to be performed to ensure that Imm
|
||||
// represents the expected signed 64-bit number.
|
||||
if (!isRV64())
|
||||
Imm = SignExtend64<32>(Imm);
|
||||
emitLoadImm(Reg, Imm, Out);
|
||||
return false;
|
||||
}
|
||||
|
||||
emitToStreamer(Out, Inst);
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" void LLVMInitializeRISCVAsmParser() {
|
||||
RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
|
||||
RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
|
||||
|
|
|
@ -102,8 +102,8 @@ class RVInst<dag outs, dag ins, string opcodestr, string argstr,
|
|||
}
|
||||
|
||||
// Pseudo instructions
|
||||
class Pseudo<dag outs, dag ins, list<dag> pattern>
|
||||
: RVInst<outs, ins, "", "", pattern, InstFormatPseudo> {
|
||||
class Pseudo<dag outs, dag ins, list<dag> pattern, string opcodestr = "", string argstr = "">
|
||||
: RVInst<outs, ins, opcodestr, argstr, pattern, InstFormatPseudo> {
|
||||
let isPseudo = 1;
|
||||
let isCodeGenOnly = 1;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,12 @@ def Tail : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
|
|||
// Operand and SDNode transformation definitions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass {
|
||||
let Name = prefix # "ImmXLen" # suffix;
|
||||
let RenderMethod = "addImmOperands";
|
||||
let DiagnosticType = !strconcat("Invalid", Name);
|
||||
}
|
||||
|
||||
class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
|
||||
let Name = prefix # "Imm" # width # suffix;
|
||||
let RenderMethod = "addImmOperands";
|
||||
|
@ -171,7 +177,9 @@ def bare_symbol : Operand<XLenVT> {
|
|||
}
|
||||
|
||||
// A parameterized register class alternative to i32imm/i64imm from Target.td.
|
||||
def ixlenimm : Operand<XLenVT>;
|
||||
def ixlenimm : Operand<XLenVT> {
|
||||
let ParserMatchClass = ImmXLenAsmOperand<"">;
|
||||
}
|
||||
|
||||
// Standalone (codegen-only) immleaf patterns.
|
||||
def simm32 : ImmLeaf<XLenVT, [{return isInt<32>(Imm);}]>;
|
||||
|
@ -440,7 +448,16 @@ def SFENCE_VMA : RVInstR<0b0001001, 0b000, OPC_SYSTEM, (outs),
|
|||
// TODO RV64I: sd
|
||||
|
||||
def : InstAlias<"nop", (ADDI X0, X0, 0)>;
|
||||
// TODO li
|
||||
|
||||
// Note that the size is 32 because up to 8 32-bit instructions are needed to
|
||||
// generate an arbitrary 64-bit immediate. However, the size does not really
|
||||
// matter since PseudoLI is currently only used in the AsmParser where it gets
|
||||
// expanded to real instructions immediately.
|
||||
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,
|
||||
isCodeGenOnly = 0, isAsmParserOnly = 1 in
|
||||
def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm:$imm), [],
|
||||
"li", "$rd, $imm">;
|
||||
|
||||
def : InstAlias<"mv $rd, $rs", (ADDI GPR:$rd, GPR:$rs, 0)>;
|
||||
def : InstAlias<"not $rd, $rs", (XORI GPR:$rd, GPR:$rs, -1)>;
|
||||
def : InstAlias<"neg $rd, $rs", (SUB GPR:$rd, X0, GPR:$rs)>;
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# RUN: llvm-mc -triple=riscv32 -mattr=+c -riscv-no-aliases < %s \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c < %s \
|
||||
# RUN: | llvm-objdump -d -riscv-no-aliases - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
|
||||
# The following check prefixes are used in this test:
|
||||
# CHECK-INST.....Match the canonical instr (tests alias to instr. mapping)
|
||||
# CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion)
|
||||
|
||||
# CHECK-EXPAND: c.li a0, 0
|
||||
li x10, 0
|
||||
# CHECK-EXPAND: c.li a0, 1
|
||||
li x10, 1
|
||||
# CHECK-EXPAND: c.li a0, -1
|
||||
li x10, -1
|
||||
# CHECK-EXPAND: addi a0, zero, 2047
|
||||
li x10, 2047
|
||||
# CHECK-EXPAND: addi a0, zero, -2047
|
||||
li x10, -2047
|
||||
# CHECK-EXPAND: c.lui a1, 1
|
||||
# CHECK-EXPAND: addi a1, a1, -2048
|
||||
li x11, 2048
|
||||
# CHECK-EXPAND: addi a1, zero, -2048
|
||||
li x11, -2048
|
||||
# CHECK-EXPAND: c.lui a1, 1
|
||||
# CHECK-EXPAND: addi a1, a1, -2047
|
||||
li x11, 2049
|
||||
# CHECK-EXPAND: lui a1, 1048575
|
||||
# CHECK-EXPAND: addi a1, a1, 2047
|
||||
li x11, -2049
|
||||
# CHECK-EXPAND: c.lui a1, 1
|
||||
# CHECK-EXPAND: c.addi a1, -1
|
||||
li x11, 4095
|
||||
# CHECK-EXPAND: lui a1, 1048575
|
||||
# CHECK-EXPAND: c.addi a1, 1
|
||||
li x11, -4095
|
||||
# CHECK-EXPAND: c.lui a2, 1
|
||||
li x12, 4096
|
||||
# CHECK-EXPAND: lui a2, 1048575
|
||||
li x12, -4096
|
||||
# CHECK-EXPAND: c.lui a2, 1
|
||||
# CHECK-EXPAND: c.addi a2, 1
|
||||
li x12, 4097
|
||||
# CHECK-EXPAND: lui a2, 1048575
|
||||
# CHECK-EXPAND: c.addi a2, -1
|
||||
li x12, -4097
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
# CHECK-EXPAND: c.addi a2, -1
|
||||
li x12, 2147483647
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
# CHECK-EXPAND: c.addi a2, 1
|
||||
li x12, -2147483647
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, -2147483648
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, -0x80000000
|
||||
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, 0x80000000
|
||||
# CHECK-EXPAND: c.li a2, -1
|
||||
li x12, 0xFFFFFFFF
|
|
@ -4,5 +4,12 @@
|
|||
# TODO ld
|
||||
# TODO sd
|
||||
|
||||
li x0, 4294967296 # CHECK: :[[@LINE]]:8: error: immediate must be an integer in the range [-2147483648, 4294967295]
|
||||
li x0, -2147483649 # CHECK: :[[@LINE]]:8: error: immediate must be an integer in the range [-2147483648, 4294967295]
|
||||
li t4, foo # CHECK: :[[@LINE]]:8: error: immediate must be an integer in the range [-2147483648, 4294967295]
|
||||
|
||||
negw x1, x2 # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
|
||||
sext.w x3, x4 # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
|
||||
|
||||
foo:
|
||||
.space 4
|
||||
|
|
|
@ -1,13 +1,73 @@
|
|||
# RUN: llvm-mc %s -triple=riscv32 -riscv-no-aliases \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-INST %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc %s -triple=riscv32 \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-ALIAS %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
|
||||
# RUN: | llvm-objdump -riscv-no-aliases -d - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-INST %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
|
||||
# RUN: | llvm-objdump -d - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-ALIAS %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
|
||||
|
||||
# The following check prefixes are used in this test:
|
||||
# CHECK-INST.....Match the canonical instr (tests alias to instr. mapping)
|
||||
# CHECK-ALIAS....Match the alias (tests instr. to alias mapping)
|
||||
# CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion)
|
||||
|
||||
|
||||
# CHECK-INST: addi a0, zero, 0
|
||||
# CHECK-ALIAS: mv a0, zero
|
||||
li x10, 0
|
||||
# CHECK-EXPAND: addi a0, zero, 1
|
||||
li x10, 1
|
||||
# CHECK-EXPAND: addi a0, zero, -1
|
||||
li x10, -1
|
||||
# CHECK-EXPAND: addi a0, zero, 2047
|
||||
li x10, 2047
|
||||
# CHECK-EXPAND: addi a0, zero, -2047
|
||||
li x10, -2047
|
||||
# CHECK-EXPAND: lui a1, 1
|
||||
# CHECK-EXPAND: addi a1, a1, -2048
|
||||
li x11, 2048
|
||||
# CHECK-EXPAND: addi a1, zero, -2048
|
||||
li x11, -2048
|
||||
# CHECK-EXPAND: lui a1, 1
|
||||
# CHECK-EXPAND: addi a1, a1, -2047
|
||||
li x11, 2049
|
||||
# CHECK-EXPAND: lui a1, 1048575
|
||||
# CHECK-EXPAND: addi a1, a1, 2047
|
||||
li x11, -2049
|
||||
# CHECK-EXPAND: lui a1, 1
|
||||
# CHECK-EXPAND: addi a1, a1, -1
|
||||
li x11, 4095
|
||||
# CHECK-EXPAND: lui a1, 1048575
|
||||
# CHECK-EXPAND: addi a1, a1, 1
|
||||
li x11, -4095
|
||||
# CHECK-EXPAND: lui a2, 1
|
||||
li x12, 4096
|
||||
# CHECK-EXPAND: lui a2, 1048575
|
||||
li x12, -4096
|
||||
# CHECK-EXPAND: lui a2, 1
|
||||
# CHECK-EXPAND: addi a2, a2, 1
|
||||
li x12, 4097
|
||||
# CHECK-EXPAND: lui a2, 1048575
|
||||
# CHECK-EXPAND: addi a2, a2, -1
|
||||
li x12, -4097
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
# CHECK-EXPAND: addi a2, a2, -1
|
||||
li x12, 2147483647
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
# CHECK-EXPAND: addi a2, a2, 1
|
||||
li x12, -2147483647
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, -2147483648
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, -0x80000000
|
||||
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, 0x80000000
|
||||
# CHECK-EXPAND: addi a2, zero, -1
|
||||
li x12, 0xFFFFFFFF
|
||||
|
||||
# CHECK-INST: csrrs t4, 3202, zero
|
||||
# CHECK-ALIAS: rdinstreth t4
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# RUN: llvm-mc -triple=riscv64 -mattr=+c -riscv-no-aliases < %s \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+c < %s \
|
||||
# RUN: | llvm-objdump -d -riscv-no-aliases - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
|
||||
# The following check prefixes are used in this test:
|
||||
# CHECK-INST.....Match the canonical instr (tests alias to instr. mapping)
|
||||
# CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion)
|
||||
|
||||
# CHECK-EXPAND: addiw a0, zero, 0
|
||||
li x10, 0
|
||||
# CHECK-EXPAND: addiw a0, zero, 1
|
||||
li x10, 1
|
||||
# CHECK-EXPAND: addiw a0, zero, -1
|
||||
li x10, -1
|
||||
# CHECK-EXPAND: addiw a0, zero, 2047
|
||||
li x10, 2047
|
||||
# CHECK-EXPAND: addiw a0, zero, -2047
|
||||
li x10, -2047
|
||||
# CHECK-EXPAND: c.lui a1, 1
|
||||
# CHECK-EXPAND: addiw a1, a1, -2048
|
||||
li x11, 2048
|
||||
# CHECK-EXPAND: addiw a1, zero, -2048
|
||||
li x11, -2048
|
||||
# CHECK-EXPAND: c.lui a1, 1
|
||||
# CHECK-EXPAND: addiw a1, a1, -2047
|
||||
li x11, 2049
|
||||
# CHECK-EXPAND: c.lui a1, 1048575
|
||||
# CHECK-EXPAND: addiw a1, a1, 2047
|
||||
li x11, -2049
|
||||
# CHECK-EXPAND: c.lui a1, 1
|
||||
# CHECK-EXPAND: c.addiw a1, -1
|
||||
li x11, 4095
|
||||
# CHECK-EXPAND: lui a1, 1048575
|
||||
# CHECK-EXPAND: c.addiw a1, 1
|
||||
li x11, -4095
|
||||
# CHECK-EXPAND: c.lui a2, 1
|
||||
li x12, 4096
|
||||
# CHECK-EXPAND: lui a2, 1048575
|
||||
li x12, -4096
|
||||
# CHECK-EXPAND: c.lui a2, 1
|
||||
# CHECK-EXPAND: c.addiw a2, 1
|
||||
li x12, 4097
|
||||
# CHECK-EXPAND: lui a2, 1048575
|
||||
# CHECK-EXPAND: c.addiw a2, -1
|
||||
li x12, -4097
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
# CHECK-EXPAND: c.addiw a2, -1
|
||||
li x12, 2147483647
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
# CHECK-EXPAND: c.addiw a2, 1
|
||||
li x12, -2147483647
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, -2147483648
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, -0x80000000
|
||||
|
||||
# CHECK-EXPAND: addiw a2, zero, 1
|
||||
# CHECK-EXPAND: c.slli a2, 31
|
||||
li x12, 0x80000000
|
||||
# CHECK-EXPAND: addiw a2, zero, 1
|
||||
# CHECK-EXPAND: c.slli a2, 32
|
||||
# CHECK-EXPAND: c.addi a2, -1
|
||||
li x12, 0xFFFFFFFF
|
||||
|
||||
# CHECK-EXPAND: addiw t0, zero, 1
|
||||
# CHECK-EXPAND: c.slli t0, 32
|
||||
li t0, 0x100000000
|
||||
# CHECK-EXPAND: addiw t1, zero, -1
|
||||
# CHECK-EXPAND: c.slli t1, 63
|
||||
li t1, 0x8000000000000000
|
||||
# CHECK-EXPAND: addiw t1, zero, -1
|
||||
# CHECK-EXPAND: c.slli t1, 63
|
||||
li t1, -0x8000000000000000
|
||||
# CHECK-EXPAND: lui t2, 9321
|
||||
# CHECK-EXPAND: addiw t2, t2, -1329
|
||||
# CHECK-EXPAND: c.slli t2, 35
|
||||
li t2, 0x1234567800000000
|
||||
# CHECK-EXPAND: addiw t3, zero, 7
|
||||
# CHECK-EXPAND: c.slli t3, 36
|
||||
# CHECK-EXPAND: c.addi t3, 11
|
||||
# CHECK-EXPAND: c.slli t3, 24
|
||||
# CHECK-EXPAND: c.addi t3, 15
|
||||
li t3, 0x700000000B00000F
|
||||
# CHECK-EXPAND: lui t4, 583
|
||||
# CHECK-EXPAND: addiw t4, t4, -1875
|
||||
# CHECK-EXPAND: c.slli t4, 14
|
||||
# CHECK-EXPAND: addi t4, t4, -947
|
||||
# CHECK-EXPAND: c.slli t4, 12
|
||||
# CHECK-EXPAND: addi t4, t4, 1511
|
||||
# CHECK-EXPAND: c.slli t4, 13
|
||||
# CHECK-EXPAND: addi t4, t4, -272
|
||||
li t4, 0x123456789abcdef0
|
||||
# CHECK-EXPAND: addiw t5, zero, -1
|
||||
li t5, 0xFFFFFFFFFFFFFFFF
|
|
@ -1,6 +1,12 @@
|
|||
# RUN: not llvm-mc %s -triple=riscv64 -riscv-no-aliases 2>&1 | FileCheck %s
|
||||
# RUN: not llvm-mc %s -triple=riscv64 2>&1 | FileCheck %s
|
||||
|
||||
li t5, 0x10000000000000000 # CHECK: :[[@LINE]]:8: error: unknown operand
|
||||
li t4, foo # CHECK: :[[@LINE]]:8: error: operand must be a constant 64-bit integer
|
||||
|
||||
rdinstreth x29 # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
|
||||
rdcycleh x27 # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
|
||||
rdtimeh x28 # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
|
||||
|
||||
foo:
|
||||
.space 8
|
||||
|
|
|
@ -1,17 +1,110 @@
|
|||
# RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-INST %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
|
||||
# RUN: | llvm-objdump -riscv-no-aliases -d - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-INST %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
|
||||
# RUN: | llvm-objdump -d - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
|
||||
|
||||
# The following check prefixes are used in this test:
|
||||
# CHECK-INST.....Match the canonical instr (tests alias to instr. mapping)
|
||||
# CHECK-ALIAS....Match the alias (tests instr. to alias mapping)
|
||||
# CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion)
|
||||
|
||||
# TODO ld
|
||||
# TODO sd
|
||||
|
||||
# CHECK-INST: addiw a0, zero, 0
|
||||
# CHECK-ALIAS: sext.w a0, zero
|
||||
li x10, 0
|
||||
# CHECK-EXPAND: addiw a0, zero, 1
|
||||
li x10, 1
|
||||
# CHECK-EXPAND: addiw a0, zero, -1
|
||||
li x10, -1
|
||||
# CHECK-EXPAND: addiw a0, zero, 2047
|
||||
li x10, 2047
|
||||
# CHECK-EXPAND: addiw a0, zero, -2047
|
||||
li x10, -2047
|
||||
# CHECK-EXPAND: lui a1, 1
|
||||
# CHECK-EXPAND: addiw a1, a1, -2048
|
||||
li x11, 2048
|
||||
# CHECK-EXPAND: addiw a1, zero, -2048
|
||||
li x11, -2048
|
||||
# CHECK-EXPAND: lui a1, 1
|
||||
# CHECK-EXPAND: addiw a1, a1, -2047
|
||||
li x11, 2049
|
||||
# CHECK-EXPAND: lui a1, 1048575
|
||||
# CHECK-EXPAND: addiw a1, a1, 2047
|
||||
li x11, -2049
|
||||
# CHECK-EXPAND: lui a1, 1
|
||||
# CHECK-EXPAND: addiw a1, a1, -1
|
||||
li x11, 4095
|
||||
# CHECK-EXPAND: lui a1, 1048575
|
||||
# CHECK-EXPAND: addiw a1, a1, 1
|
||||
li x11, -4095
|
||||
# CHECK-EXPAND: lui a2, 1
|
||||
li x12, 4096
|
||||
# CHECK-EXPAND: lui a2, 1048575
|
||||
li x12, -4096
|
||||
# CHECK-EXPAND: lui a2, 1
|
||||
# CHECK-EXPAND: addiw a2, a2, 1
|
||||
li x12, 4097
|
||||
# CHECK-EXPAND: lui a2, 1048575
|
||||
# CHECK-EXPAND: addiw a2, a2, -1
|
||||
li x12, -4097
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
# CHECK-EXPAND: addiw a2, a2, -1
|
||||
li x12, 2147483647
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
# CHECK-EXPAND: addiw a2, a2, 1
|
||||
li x12, -2147483647
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, -2147483648
|
||||
# CHECK-EXPAND: lui a2, 524288
|
||||
li x12, -0x80000000
|
||||
|
||||
# CHECK-EXPAND: addiw a2, zero, 1
|
||||
# CHECK-EXPAND: slli a2, a2, 31
|
||||
li x12, 0x80000000
|
||||
# CHECK-EXPAND: addiw a2, zero, 1
|
||||
# CHECK-EXPAND: slli a2, a2, 32
|
||||
# CHECK-EXPAND: addi a2, a2, -1
|
||||
li x12, 0xFFFFFFFF
|
||||
|
||||
# CHECK-EXPAND: addiw t0, zero, 1
|
||||
# CHECK-EXPAND: slli t0, t0, 32
|
||||
li t0, 0x100000000
|
||||
# CHECK-EXPAND: addiw t1, zero, -1
|
||||
# CHECK-EXPAND: slli t1, t1, 63
|
||||
li t1, 0x8000000000000000
|
||||
# CHECK-EXPAND: addiw t1, zero, -1
|
||||
# CHECK-EXPAND: slli t1, t1, 63
|
||||
li t1, -0x8000000000000000
|
||||
# CHECK-EXPAND: lui t2, 9321
|
||||
# CHECK-EXPAND: addiw t2, t2, -1329
|
||||
# CHECK-EXPAND: slli t2, t2, 35
|
||||
li t2, 0x1234567800000000
|
||||
# CHECK-EXPAND: addiw t3, zero, 7
|
||||
# CHECK-EXPAND: slli t3, t3, 36
|
||||
# CHECK-EXPAND: addi t3, t3, 11
|
||||
# CHECK-EXPAND: slli t3, t3, 24
|
||||
# CHECK-EXPAND: addi t3, t3, 15
|
||||
li t3, 0x700000000B00000F
|
||||
# CHECK-EXPAND: lui t4, 583
|
||||
# CHECK-EXPAND: addiw t4, t4, -1875
|
||||
# CHECK-EXPAND: slli t4, t4, 14
|
||||
# CHECK-EXPAND: addi t4, t4, -947
|
||||
# CHECK-EXPAND: slli t4, t4, 12
|
||||
# CHECK-EXPAND: addi t4, t4, 1511
|
||||
# CHECK-EXPAND: slli t4, t4, 13
|
||||
# CHECK-EXPAND: addi t4, t4, -272
|
||||
li t4, 0x123456789abcdef0
|
||||
# CHECK-EXPAND: addiw t5, zero, -1
|
||||
li t5, 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
# CHECK-INST: subw t6, zero, ra
|
||||
# CHECK-ALIAS: negw t6, ra
|
||||
negw x31, x1
|
||||
|
|
|
@ -1,23 +1,28 @@
|
|||
# RUN: llvm-mc %s -triple=riscv32 -riscv-no-aliases \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-INST %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc %s -triple=riscv32 \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases\
|
||||
# RUN: | FileCheck -check-prefix=CHECK-INST %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
|
||||
# RUN: | llvm-objdump -d -riscv-no-aliases - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-INST %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
|
||||
# RUN: | llvm-objdump -d - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
|
||||
# RUN: | llvm-objdump -d -riscv-no-aliases - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-INST %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
|
||||
# RUN: | llvm-objdump -d - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
|
||||
|
||||
# The following check prefixes are used in this test:
|
||||
# CHECK-INST.....Match the canonical instr (tests alias to instr. mapping)
|
||||
# CHECK-ALIAS....Match the alias (tests instr. to alias mapping)
|
||||
# CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion)
|
||||
|
||||
# TODO la
|
||||
# TODO lb lh lw
|
||||
|
@ -26,7 +31,7 @@
|
|||
# CHECK-INST: addi zero, zero, 0
|
||||
# CHECK-ALIAS: nop
|
||||
nop
|
||||
# TODO li
|
||||
|
||||
# CHECK-INST: addi t6, zero, 0
|
||||
# CHECK-ALIAS: mv t6, zero
|
||||
mv x31, zero
|
||||
|
|
Loading…
Reference in New Issue