Index: llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -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 + using namespace llvm; // Include the auto-generated portion of the compress emitter. @@ -47,7 +51,7 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ } 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::min(), + std::numeric_limits::max()); case Match_InvalidUImmLog2XLen: if (isRV64()) return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); @@ -1067,6 +1099,111 @@ 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 X(getTheRISCV32Target()); RegisterMCAsmParser Y(getTheRISCV64Target()); Index: llvm/trunk/lib/Target/RISCV/RISCVInstrFormats.td =================================================================== --- llvm/trunk/lib/Target/RISCV/RISCVInstrFormats.td +++ llvm/trunk/lib/Target/RISCV/RISCVInstrFormats.td @@ -102,8 +102,8 @@ } // Pseudo instructions -class Pseudo pattern> - : RVInst { +class Pseudo pattern, string opcodestr = "", string argstr = ""> + : RVInst { let isPseudo = 1; let isCodeGenOnly = 1; } Index: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td +++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td @@ -46,6 +46,12 @@ // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// +class ImmXLenAsmOperand : AsmOperandClass { + let Name = prefix # "ImmXLen" # suffix; + let RenderMethod = "addImmOperands"; + let DiagnosticType = !strconcat("Invalid", Name); +} + class ImmAsmOperand : AsmOperandClass { let Name = prefix # "Imm" # width # suffix; let RenderMethod = "addImmOperands"; @@ -171,7 +177,9 @@ } // A parameterized register class alternative to i32imm/i64imm from Target.td. -def ixlenimm : Operand; +def ixlenimm : Operand { + let ParserMatchClass = ImmXLenAsmOperand<"">; +} // Standalone (codegen-only) immleaf patterns. def simm32 : ImmLeaf(Imm);}]>; @@ -440,7 +448,16 @@ // 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)>; Index: llvm/trunk/test/MC/RISCV/rv32c-aliases-valid.s =================================================================== --- llvm/trunk/test/MC/RISCV/rv32c-aliases-valid.s +++ llvm/trunk/test/MC/RISCV/rv32c-aliases-valid.s @@ -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 Index: llvm/trunk/test/MC/RISCV/rv32i-aliases-invalid.s =================================================================== --- llvm/trunk/test/MC/RISCV/rv32i-aliases-invalid.s +++ llvm/trunk/test/MC/RISCV/rv32i-aliases-invalid.s @@ -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 Index: llvm/trunk/test/MC/RISCV/rv32i-aliases-valid.s =================================================================== --- llvm/trunk/test/MC/RISCV/rv32i-aliases-valid.s +++ llvm/trunk/test/MC/RISCV/rv32i-aliases-valid.s @@ -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 Index: llvm/trunk/test/MC/RISCV/rv64c-aliases-valid.s =================================================================== --- llvm/trunk/test/MC/RISCV/rv64c-aliases-valid.s +++ llvm/trunk/test/MC/RISCV/rv64c-aliases-valid.s @@ -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 Index: llvm/trunk/test/MC/RISCV/rv64i-aliases-invalid.s =================================================================== --- llvm/trunk/test/MC/RISCV/rv64i-aliases-invalid.s +++ llvm/trunk/test/MC/RISCV/rv64i-aliases-invalid.s @@ -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 Index: llvm/trunk/test/MC/RISCV/rv64i-aliases-valid.s =================================================================== --- llvm/trunk/test/MC/RISCV/rv64i-aliases-valid.s +++ llvm/trunk/test/MC/RISCV/rv64i-aliases-valid.s @@ -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 Index: llvm/trunk/test/MC/RISCV/rvi-aliases-valid.s =================================================================== --- llvm/trunk/test/MC/RISCV/rvi-aliases-valid.s +++ llvm/trunk/test/MC/RISCV/rvi-aliases-valid.s @@ -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