Skip to content

Commit ad01e0a

Browse files
authored
[RISCV][Xqcilo] Load/Store Pseudos (#134931)
This adds `qc.e.l<type> <reg>, <symbol>` and `qc.e.s<type> <reg>, <symbol>, <reg>` pseudos for the corresponding Xqcilo instructions. These emit as an AUIPC + (Standard) Load/Store pair, because this sequence is shorter and can be relaxed back into the equivalent Xqcilo load/store instruction in the right circumstances.
1 parent ab95005 commit ad01e0a

File tree

4 files changed

+138
-0
lines changed

4 files changed

+138
-0
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3746,18 +3746,23 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
37463746
emitLoadTLSGDAddress(Inst, IDLoc, Out);
37473747
return false;
37483748
case RISCV::PseudoLB:
3749+
case RISCV::PseudoQC_E_LB:
37493750
emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
37503751
return false;
37513752
case RISCV::PseudoLBU:
3753+
case RISCV::PseudoQC_E_LBU:
37523754
emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
37533755
return false;
37543756
case RISCV::PseudoLH:
3757+
case RISCV::PseudoQC_E_LH:
37553758
emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
37563759
return false;
37573760
case RISCV::PseudoLHU:
3761+
case RISCV::PseudoQC_E_LHU:
37583762
emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
37593763
return false;
37603764
case RISCV::PseudoLW:
3765+
case RISCV::PseudoQC_E_LW:
37613766
emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
37623767
return false;
37633768
case RISCV::PseudoLWU:
@@ -3776,12 +3781,15 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
37763781
emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
37773782
return false;
37783783
case RISCV::PseudoSB:
3784+
case RISCV::PseudoQC_E_SB:
37793785
emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
37803786
return false;
37813787
case RISCV::PseudoSH:
3788+
case RISCV::PseudoQC_E_SH:
37823789
emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
37833790
return false;
37843791
case RISCV::PseudoSW:
3792+
case RISCV::PseudoQC_E_SW:
37853793
emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
37863794
return false;
37873795
case RISCV::PseudoSD:

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,23 @@ def PseudoLongQC_E_BGEI : LongBcciPseudo<simm16nonzero, 10>;
11861186
def PseudoLongQC_E_BLTUI : LongBcciPseudo<uimm16nonzero, 10>;
11871187
def PseudoLongQC_E_BGEUI : LongBcciPseudo<uimm16nonzero, 10>;
11881188

1189+
// Load/Store pseudos with QC.E.* Mnemonics. These expand to an AUIPC +
1190+
// (Standard) Load/Store sequence, as this can materialize all 32-bit addresses,
1191+
// and is shorter than e.g. an AUIPC + Xqcilo Load/Store sequence. These
1192+
// sequences can be turned back into a single Xqcilo instruction using linker
1193+
// relaxation.
1194+
let Predicates = [HasVendorXqcilo, IsRV32] in {
1195+
def PseudoQC_E_LB : PseudoLoad<"qc.e.lb">;
1196+
def PseudoQC_E_LBU : PseudoLoad<"qc.e.lbu">;
1197+
def PseudoQC_E_LH : PseudoLoad<"qc.e.lh">;
1198+
def PseudoQC_E_LHU : PseudoLoad<"qc.e.lhu">;
1199+
def PseudoQC_E_LW : PseudoLoad<"qc.e.lw">;
1200+
1201+
def PseudoQC_E_SB : PseudoStore<"qc.e.sb">;
1202+
def PseudoQC_E_SH : PseudoStore<"qc.e.sh">;
1203+
def PseudoQC_E_SW : PseudoStore<"qc.e.sw">;
1204+
} // Predicates = [HasVendorXqcilo, IsRV32]
1205+
11891206
//===----------------------------------------------------------------------===//
11901207
// Code Gen Patterns
11911208
//===----------------------------------------------------------------------===//
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Xqcilo - Qualcomm uC Large Offset Load Store extension
2+
# RUN: not llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilo \
3+
# RUN: 2>&1 | FileCheck -check-prefixes=CHECK-ENABLED %s
4+
# RUN: not llvm-mc %s -triple=riscv32 -mattr=-experimental-xqcilo \
5+
# RUN: 2>&1 | FileCheck -check-prefixes=CHECK-DISABLED %s
6+
7+
# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
8+
# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
9+
qc.e.lb a0, 0xf000
10+
11+
# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
12+
# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
13+
qc.e.lb a0, 0xf000
14+
15+
# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
16+
# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
17+
qc.e.lbu a0, 0xf000
18+
19+
# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
20+
# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
21+
qc.e.lh a0, 0xf000
22+
23+
# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
24+
# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
25+
qc.e.lhu a0, 0xf000
26+
27+
# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
28+
# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
29+
qc.e.lw a0, 0xf000
30+
31+
# CHECK-ENABLED: [[@LINE+2]]:21: error: invalid operand for instruction
32+
# CHECK-DISABLED: [[@LINE+1]]:21: error: invalid operand for instruction
33+
qc.e.sb a0, 0xf000, t0
34+
35+
# CHECK-ENABLED: [[@LINE+2]]:21: error: invalid operand for instruction
36+
# CHECK-DISABLED: [[@LINE+1]]:21: error: invalid operand for instruction
37+
qc.e.sh a0, 0xf000, t0
38+
39+
# CHECK-ENABLED: [[@LINE+2]]:21: error: invalid operand for instruction
40+
# CHECK-DISABLED: [[@LINE+1]]:21: error: invalid operand for instruction
41+
qc.e.sw a0, 0xf000, t0
42+
43+
# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
44+
qc.e.lb a0, undefined
45+
# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
46+
qc.e.lbu a0, undefined
47+
# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
48+
qc.e.lh a0, undefined
49+
# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
50+
qc.e.lhu a0, undefined
51+
# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
52+
qc.e.lw a0, undefined
53+
# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
54+
qc.e.sb a0, undefined, t0
55+
# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
56+
qc.e.sh a0, undefined, t0
57+
# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
58+
qc.e.sw a0, undefined, t0
59+
60+
# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
61+
# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
62+
qc.e.sb a0, undefined
63+
64+
# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
65+
# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
66+
qc.e.sh a0, undefined
67+
68+
# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
69+
# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
70+
qc.e.sw a0, undefined
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Xqcilo - Qualcomm uC Large Offset Load Store extension
2+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilo \
3+
# RUN: | FileCheck -check-prefixes=CHECK %s
4+
5+
# CHECK-LABEL: .Lpcrel_hi0
6+
# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
7+
# CHECK-NEXT: lb a0, %pcrel_lo(.Lpcrel_hi0)(a0)
8+
qc.e.lb a0, undefined
9+
10+
# CHECK-LABEL: .Lpcrel_hi1
11+
# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
12+
# CHECK-NEXT: lbu a0, %pcrel_lo(.Lpcrel_hi1)(a0)
13+
qc.e.lbu a0, undefined
14+
15+
# CHECK-LABEL: .Lpcrel_hi2
16+
# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
17+
# CHECK-NEXT: lh a0, %pcrel_lo(.Lpcrel_hi2)(a0)
18+
qc.e.lh a0, undefined
19+
20+
# CHECK-LABEL: .Lpcrel_hi3
21+
# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
22+
# CHECK-NEXT: lhu a0, %pcrel_lo(.Lpcrel_hi3)(a0)
23+
qc.e.lhu a0, undefined
24+
25+
# CHECK-LABEL: .Lpcrel_hi4
26+
# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
27+
# CHECK-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi4)(a0)
28+
qc.e.lw a0, undefined
29+
30+
# CHECK-LABEL: .Lpcrel_hi5
31+
# CHECK-NEXT: auipc t0, %pcrel_hi(undefined)
32+
# CHECK-NEXT: sb a0, %pcrel_lo(.Lpcrel_hi5)(t0)
33+
qc.e.sb a0, undefined, t0
34+
35+
# CHECK-LABEL: .Lpcrel_hi6
36+
# CHECK-NEXT: auipc t0, %pcrel_hi(undefined)
37+
# CHECK-NEXT: sh a0, %pcrel_lo(.Lpcrel_hi6)(t0)
38+
qc.e.sh a0, undefined, t0
39+
40+
# CHECK-LABEL: .Lpcrel_hi7
41+
# CHECK-NEXT: auipc t0, %pcrel_hi(undefined)
42+
# CHECK-NEXT: sw a0, %pcrel_lo(.Lpcrel_hi7)(t0)
43+
qc.e.sw a0, undefined, t0

0 commit comments

Comments
 (0)