mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-10 14:36:12 +00:00
[RISCV] MC layer support for the standard RV64I instructions
llvm-svn: 320024
This commit is contained in:
parent
e4dd444e6f
commit
f0d4f4bb55
@ -31,6 +31,7 @@ struct RISCVOperand;
|
||||
|
||||
class RISCVAsmParser : public MCTargetAsmParser {
|
||||
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
|
||||
bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
|
||||
|
||||
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
|
||||
unsigned Kind) override;
|
||||
@ -91,6 +92,8 @@ struct RISCVOperand : public MCParsedAsmOperand {
|
||||
Immediate,
|
||||
} Kind;
|
||||
|
||||
bool IsRV64;
|
||||
|
||||
struct RegOp {
|
||||
unsigned RegNum;
|
||||
};
|
||||
@ -111,6 +114,7 @@ struct RISCVOperand : public MCParsedAsmOperand {
|
||||
public:
|
||||
RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
|
||||
Kind = o.Kind;
|
||||
IsRV64 = o.IsRV64;
|
||||
StartLoc = o.StartLoc;
|
||||
EndLoc = o.EndLoc;
|
||||
switch (Kind) {
|
||||
@ -202,6 +206,16 @@ public:
|
||||
return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
|
||||
}
|
||||
|
||||
bool isUImmLog2XLen() const {
|
||||
int64_t Imm;
|
||||
RISCVMCExpr::VariantKind VK;
|
||||
if (!isImm())
|
||||
return false;
|
||||
if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None)
|
||||
return false;
|
||||
return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
|
||||
}
|
||||
|
||||
bool isUImm5() const {
|
||||
int64_t Imm;
|
||||
RISCVMCExpr::VariantKind VK;
|
||||
@ -259,6 +273,8 @@ public:
|
||||
SMLoc getStartLoc() const override { return StartLoc; }
|
||||
/// getEndLoc - Gets location of the last token of this operand
|
||||
SMLoc getEndLoc() const override { return EndLoc; }
|
||||
/// True if this operand is for an RV64 instruction
|
||||
bool isRV64() const { return IsRV64; }
|
||||
|
||||
unsigned getReg() const override {
|
||||
assert(Kind == Register && "Invalid type access!");
|
||||
@ -290,29 +306,33 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
|
||||
static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
|
||||
bool IsRV64) {
|
||||
auto Op = make_unique<RISCVOperand>(Token);
|
||||
Op->Tok = Str;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = S;
|
||||
Op->IsRV64 = IsRV64;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
|
||||
SMLoc E) {
|
||||
SMLoc E, bool IsRV64) {
|
||||
auto Op = make_unique<RISCVOperand>(Register);
|
||||
Op->Reg.RegNum = RegNo;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
Op->IsRV64 = IsRV64;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
|
||||
SMLoc E) {
|
||||
SMLoc E, bool IsRV64) {
|
||||
auto Op = make_unique<RISCVOperand>(Immediate);
|
||||
Op->Imm.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
Op->IsRV64 = IsRV64;
|
||||
return Op;
|
||||
}
|
||||
|
||||
@ -482,6 +502,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
}
|
||||
return Error(ErrorLoc, "invalid operand for instruction");
|
||||
}
|
||||
case Match_InvalidUImmLog2XLen:
|
||||
if (isRV64())
|
||||
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
|
||||
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
|
||||
case Match_InvalidUImm5:
|
||||
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
|
||||
case Match_InvalidSImm12:
|
||||
@ -562,16 +586,16 @@ OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
|
||||
}
|
||||
}
|
||||
if (HadParens)
|
||||
Operands.push_back(RISCVOperand::createToken("(", FirstS));
|
||||
Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
|
||||
SMLoc S = getLoc();
|
||||
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
|
||||
getLexer().Lex();
|
||||
Operands.push_back(RISCVOperand::createReg(RegNo, S, E));
|
||||
Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
|
||||
}
|
||||
|
||||
if (HadParens) {
|
||||
getParser().Lex(); // Eat ')'
|
||||
Operands.push_back(RISCVOperand::createToken(")", getLoc()));
|
||||
Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
|
||||
}
|
||||
|
||||
return MatchOperand_Success;
|
||||
@ -605,7 +629,7 @@ OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
|
||||
return parseOperandWithModifier(Operands);
|
||||
}
|
||||
|
||||
Operands.push_back(RISCVOperand::createImm(Res, S, E));
|
||||
Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
@ -645,7 +669,7 @@ RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
|
||||
}
|
||||
|
||||
const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
|
||||
Operands.push_back(RISCVOperand::createImm(ModExpr, S, E));
|
||||
Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
@ -657,7 +681,7 @@ RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
|
||||
}
|
||||
|
||||
getParser().Lex(); // Eat '('
|
||||
Operands.push_back(RISCVOperand::createToken("(", getLoc()));
|
||||
Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
|
||||
|
||||
if (parseRegister(Operands) != MatchOperand_Success) {
|
||||
Error(getLoc(), "expected register");
|
||||
@ -670,7 +694,7 @@ RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
|
||||
}
|
||||
|
||||
getParser().Lex(); // Eat ')'
|
||||
Operands.push_back(RISCVOperand::createToken(")", getLoc()));
|
||||
Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
|
||||
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
@ -700,7 +724,7 @@ bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
|
||||
StringRef Name, SMLoc NameLoc,
|
||||
OperandVector &Operands) {
|
||||
// First operand is token for instruction
|
||||
Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
|
||||
Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
|
||||
|
||||
// If there are no more operands, then finish
|
||||
if (getLexer().is(AsmToken::EndOfStatement))
|
||||
|
@ -40,6 +40,8 @@ def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">,
|
||||
|
||||
def Feature64Bit
|
||||
: SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">;
|
||||
def IsRV64 : Predicate<"Subtarget->is64Bit()">,
|
||||
AssemblerPredicate<"Feature64Bit">;
|
||||
|
||||
def RV64 : HwMode<"+64bit">;
|
||||
def RV32 : HwMode<"-64bit">;
|
||||
|
@ -188,6 +188,23 @@ class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
|
||||
class RVInstIShift<bit arithshift, bits<3> funct3, RISCVOpcode opcode,
|
||||
dag outs, dag ins, string opcodestr, string argstr>
|
||||
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
|
||||
bits<6> shamt;
|
||||
bits<5> rs1;
|
||||
bits<5> rd;
|
||||
|
||||
let Inst{31} = 0;
|
||||
let Inst{30} = arithshift;
|
||||
let Inst{29-26} = 0;
|
||||
let Inst{25-20} = shamt;
|
||||
let Inst{19-15} = rs1;
|
||||
let Inst{14-12} = funct3;
|
||||
let Inst{11-7} = rd;
|
||||
let Opcode = opcode.Value;
|
||||
}
|
||||
|
||||
class RVInstIShiftW<bit arithshift, bits<3> funct3, RISCVOpcode opcode,
|
||||
dag outs, dag ins, string opcodestr, string argstr>
|
||||
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
|
||||
bits<5> shamt;
|
||||
bits<5> rs1;
|
||||
bits<5> rd;
|
||||
|
@ -69,6 +69,22 @@ def fencearg : Operand<XLenVT> {
|
||||
let DecoderMethod = "decodeUImmOperand<4>";
|
||||
}
|
||||
|
||||
def UImmLog2XLenAsmOperand : AsmOperandClass {
|
||||
let Name = "UImmLog2XLen";
|
||||
let RenderMethod = "addImmOperands";
|
||||
let DiagnosticType = "InvalidUImmLog2XLen";
|
||||
}
|
||||
|
||||
def uimmlog2xlen : Operand<XLenVT>, ImmLeaf<XLenVT, [{
|
||||
if (Subtarget->is64Bit())
|
||||
return isUInt<6>(Imm);
|
||||
return isUInt<5>(Imm);
|
||||
}]> {
|
||||
let ParserMatchClass = UImmLog2XLenAsmOperand;
|
||||
// TODO: should ensure invalid shamt is rejected when decoding.
|
||||
let DecoderMethod = "decodeUImmOperand<6>";
|
||||
}
|
||||
|
||||
def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> {
|
||||
let ParserMatchClass = UImmAsmOperand<5>;
|
||||
let DecoderMethod = "decodeUImmOperand<5>";
|
||||
@ -161,7 +177,7 @@ class ALU_ri<bits<3> funct3, string opcodestr>
|
||||
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
||||
class Shift_ri<bit arithshift, bits<3> funct3, string opcodestr>
|
||||
: RVInstIShift<arithshift, funct3, OPC_OP_IMM, (outs GPR:$rd),
|
||||
(ins GPR:$rs1, uimm5:$shamt), opcodestr,
|
||||
(ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
|
||||
"$rd, $rs1, $shamt">;
|
||||
|
||||
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
||||
@ -180,6 +196,17 @@ class CSR_ii<bits<3> funct3, string opcodestr> :
|
||||
(ins uimm12:$imm12, uimm5:$rs1),
|
||||
opcodestr, "$rd, $imm12, $rs1">;
|
||||
|
||||
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
||||
class ShiftW_ri<bit arithshift, bits<3> funct3, string opcodestr>
|
||||
: RVInstIShiftW<arithshift, funct3, OPC_OP_IMM_32, (outs GPR:$rd),
|
||||
(ins GPR:$rs1, uimm5:$shamt), opcodestr,
|
||||
"$rd, $rs1, $shamt">;
|
||||
|
||||
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
||||
class ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
|
||||
: RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd),
|
||||
(ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -279,6 +306,29 @@ def CSRRWI : CSR_ii<0b101, "csrrwi">;
|
||||
def CSRRSI : CSR_ii<0b110, "csrrsi">;
|
||||
def CSRRCI : CSR_ii<0b111, "csrrci">;
|
||||
|
||||
/// RV64I instructions
|
||||
|
||||
let Predicates = [IsRV64] in {
|
||||
def LWU : Load_ri<0b110, "lwu">;
|
||||
def LD : Load_ri<0b011, "ld">;
|
||||
def SD : Store_rri<0b011, "sd">;
|
||||
|
||||
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
||||
def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd),
|
||||
(ins GPR:$rs1, simm12:$imm12),
|
||||
"addiw", "$rd, $rs1, $imm12">;
|
||||
|
||||
def SLLIW : ShiftW_ri<0, 0b001, "slliw">;
|
||||
def SRLIW : ShiftW_ri<0, 0b101, "srliw">;
|
||||
def SRAIW : ShiftW_ri<1, 0b101, "sraiw">;
|
||||
|
||||
def ADDW : ALUW_rr<0b0000000, 0b000, "addw">;
|
||||
def SUBW : ALUW_rr<0b0100000, 0b000, "subw">;
|
||||
def SLLW : ALUW_rr<0b0000000, 0b001, "sllw">;
|
||||
def SRLW : ALUW_rr<0b0000000, 0b101, "srlw">;
|
||||
def SRAW : ALUW_rr<0b0100000, 0b101, "sraw">;
|
||||
} // Predicates = [IsRV64]
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pseudo-instructions and codegen patterns
|
||||
//
|
||||
@ -293,9 +343,9 @@ class PatGprGpr<SDPatternOperator OpNode, RVInstR Inst>
|
||||
: Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>;
|
||||
class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst>
|
||||
: Pat<(OpNode GPR:$rs1, simm12:$imm12), (Inst GPR:$rs1, simm12:$imm12)>;
|
||||
class PatGprUimm5<SDPatternOperator OpNode, RVInstIShift Inst>
|
||||
: Pat<(OpNode GPR:$rs1, uimm5:$shamt),
|
||||
(Inst GPR:$rs1, uimm5:$shamt)>;
|
||||
class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst>
|
||||
: Pat<(OpNode GPR:$rs1, uimmlog2xlen:$shamt),
|
||||
(Inst GPR:$rs1, uimmlog2xlen:$shamt)>;
|
||||
|
||||
/// Immediates
|
||||
|
||||
@ -315,11 +365,11 @@ def : PatGprSimm12<and, ANDI>;
|
||||
def : PatGprGpr<xor, XOR>;
|
||||
def : PatGprSimm12<xor, XORI>;
|
||||
def : PatGprGpr<shl, SLL>;
|
||||
def : PatGprUimm5<shl, SLLI>;
|
||||
def : PatGprUimmLog2XLen<shl, SLLI>;
|
||||
def : PatGprGpr<srl, SRL>;
|
||||
def : PatGprUimm5<srl, SRLI>;
|
||||
def : PatGprUimmLog2XLen<srl, SRLI>;
|
||||
def : PatGprGpr<sra, SRA>;
|
||||
def : PatGprUimm5<sra, SRAI>;
|
||||
def : PatGprUimmLog2XLen<sra, SRAI>;
|
||||
|
||||
/// Setcc
|
||||
|
||||
|
@ -111,8 +111,8 @@ slti a10, a2, 0x20 # CHECK: :[[@LINE]]:6: error: invalid operand for instruction
|
||||
slt x32, s0, s0 # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
|
||||
|
||||
# RV64I mnemonics
|
||||
addiw a0, sp, 100 # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
|
||||
sraw t0, s2, zero # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
|
||||
addiw a0, sp, 100 # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
|
||||
sraw t0, s2, zero # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
|
||||
|
||||
# Invalid operand types
|
||||
xori sp, 22, 220 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction
|
||||
|
20
test/MC/RISCV/rv64i-invalid.s
Normal file
20
test/MC/RISCV/rv64i-invalid.s
Normal file
@ -0,0 +1,20 @@
|
||||
# RUN: not llvm-mc -triple riscv64 < %s 2>&1 | FileCheck %s
|
||||
|
||||
# Out of range immediates
|
||||
## uimm5
|
||||
slliw a0, a0, 32 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
|
||||
srliw a0, a0, -1 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
|
||||
sraiw a0, a0, -19 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
|
||||
|
||||
## simm12
|
||||
addiw a0, a1, -2049 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [-2048, 2047]
|
||||
ld ra, 2048(sp) # CHECK: :[[@LINE]]:8: error: immediate must be an integer in the range [-2048, 2047]
|
||||
|
||||
# Illegal operand modifier
|
||||
## uimm5
|
||||
slliw a0, a0, %lo(1) # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
|
||||
srliw a0, a0, %lo(a) # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
|
||||
sraiw a0, a0, %hi(2) # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31]
|
||||
|
||||
## simm12
|
||||
addiw a0, a1, %hi(foo) # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [-2048, 2047]
|
98
test/MC/RISCV/rv64i-valid.s
Normal file
98
test/MC/RISCV/rv64i-valid.s
Normal file
@ -0,0 +1,98 @@
|
||||
# RUN: llvm-mc %s -triple=riscv64 -show-encoding \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
|
||||
# RUN: | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INST %s
|
||||
|
||||
# CHECK-INST: lwu zero, 4(ra)
|
||||
# CHECK: encoding: [0x03,0xe0,0x40,0x00]
|
||||
lwu x0, 4(x1)
|
||||
# CHECK-INST: lwu sp, 4(gp)
|
||||
# CHECK: encoding: [0x03,0xe1,0x41,0x00]
|
||||
lwu x2, +4(x3)
|
||||
# CHECK-INST: lwu tp, -2048(t0)
|
||||
# CHECK: encoding: [0x03,0xe2,0x02,0x80]
|
||||
lwu x4, -2048(x5)
|
||||
# CHECK-INST: lwu t1, -2048(t2)
|
||||
# CHECK: encoding: [0x03,0xe3,0x03,0x80]
|
||||
lwu x6, %lo(2048)(x7)
|
||||
# CHECK-INST: lwu s0, 2047(s1)
|
||||
# CHECK: encoding: [0x03,0xe4,0xf4,0x7f]
|
||||
lwu x8, 2047(x9)
|
||||
|
||||
# CHECK-INST: ld a0, -2048(a1)
|
||||
# CHECK: encoding: [0x03,0xb5,0x05,0x80]
|
||||
ld x10, -2048(x11)
|
||||
# CHECK-INST: ld a2, -2048(a3)
|
||||
# CHECK: encoding: [0x03,0xb6,0x06,0x80]
|
||||
ld x12, %lo(2048)(x13)
|
||||
# CHECK-INST: ld a4, 2047(a5)
|
||||
# CHECK: encoding: [0x03,0xb7,0xf7,0x7f]
|
||||
ld x14, 2047(x15)
|
||||
|
||||
# CHECK-INST: sd a6, -2048(a7)
|
||||
# CHECK: encoding: [0x23,0xb0,0x08,0x81]
|
||||
sd x16, -2048(x17)
|
||||
# CHECK-INST: sd s2, -2048(s3)
|
||||
# CHECK: encoding: [0x23,0xb0,0x29,0x81]
|
||||
sd x18, %lo(2048)(x19)
|
||||
# CHECK-INST: sd s4, 2047(s5)
|
||||
# CHECK: encoding: [0xa3,0xbf,0x4a,0x7f]
|
||||
sd x20, 2047(x21)
|
||||
|
||||
# CHECK-INST: slli s6, s7, 45
|
||||
# CHECK: encoding: [0x13,0x9b,0xdb,0x02]
|
||||
slli x22, x23, 45
|
||||
# CHECK-INST: srli s8, s9, 0
|
||||
# CHECK: encoding: [0x13,0xdc,0x0c,0x00]
|
||||
srli x24, x25, 0
|
||||
# CHECK-INST: srai s10, s11, 31
|
||||
# CHECK: encoding: [0x13,0xdd,0xfd,0x41]
|
||||
srai x26, x27, 31
|
||||
|
||||
# CHECK-INST: addiw t3, t4, -2048
|
||||
# CHECK: encoding: [0x1b,0x8e,0x0e,0x80]
|
||||
addiw x28, x29, -2048
|
||||
# CHECK-INST: addiw t5, t6, 2047
|
||||
# CHECK: encoding: [0x1b,0x8f,0xff,0x7f]
|
||||
addiw x30, x31, 2047
|
||||
|
||||
# CHECK-INST: slliw zero, ra, 0
|
||||
# CHECK: encoding: [0x1b,0x90,0x00,0x00]
|
||||
slliw zero, ra, 0
|
||||
# CHECK-INST: slliw sp, gp, 31
|
||||
# CHECK: encoding: [0x1b,0x91,0xf1,0x01]
|
||||
slliw sp, gp, 31
|
||||
# CHECK-INST: srliw tp, t0, 0
|
||||
# CHECK: encoding: [0x1b,0xd2,0x02,0x00]
|
||||
srliw tp, t0, 0
|
||||
# CHECK-INST: srliw t1, t2, 31
|
||||
# CHECK: encoding: [0x1b,0xd3,0xf3,0x01]
|
||||
srliw t1, t2, 31
|
||||
# CHECK-INST: sraiw s0, s1, 0
|
||||
# CHECK: encoding: [0x1b,0xd4,0x04,0x40]
|
||||
sraiw s0, s1, 0
|
||||
# CHECK-INST: sraiw a0, a1, 31
|
||||
# CHECK: encoding: [0x1b,0xd5,0xf5,0x41]
|
||||
sraiw a0, a1, 31
|
||||
|
||||
# CHECK-INST: addw a2, a3, a4
|
||||
# CHECK: encoding: [0x3b,0x86,0xe6,0x00]
|
||||
addw a2, a3, a4
|
||||
# CHECK-INST: addw a5, a6, a7
|
||||
# CHECK: encoding: [0xbb,0x07,0x18,0x01]
|
||||
addw a5, a6, a7
|
||||
# CHECK-INST: subw s2, s3, s4
|
||||
# CHECK: encoding: [0x3b,0x89,0x49,0x41]
|
||||
subw s2, s3, s4
|
||||
# CHECK-INST: subw s5, s6, s7
|
||||
# CHECK: encoding: [0xbb,0x0a,0x7b,0x41]
|
||||
subw s5, s6, s7
|
||||
# CHECK-INST: sllw s8, s9, s10
|
||||
# CHECK: encoding: [0x3b,0x9c,0xac,0x01]
|
||||
sllw s8, s9, s10
|
||||
# CHECK-INST: srlw s11, t3, t4
|
||||
# CHECK: encoding: [0xbb,0x5d,0xde,0x01]
|
||||
srlw s11, t3, t4
|
||||
# CHECK-INST: sraw t5, t6, zero
|
||||
# CHECK: encoding: [0x3b,0xdf,0x0f,0x40]
|
||||
sraw t5, t6, zero
|
Loading…
x
Reference in New Issue
Block a user