Skip to content

Commit 1eea6b7

Browse files
committed
arcv: apex: Add volatile variants for instructions with side effects.
Introduce "unspec_volatile" to handle APEX instructions that have side effects and must not be optimized away by the compiler. When an instruction is defined with the "side_effect" attribute via preventing optimizations such as common subexpression elimination, loop-invariant motion, or dead code elimination. Instructions with no destination register are treated as volatile. Signed-off-by: Luis Silva <[email protected]>
1 parent 0743c55 commit 1eea6b7

File tree

5 files changed

+106
-13
lines changed

5 files changed

+106
-13
lines changed

gcc/config/riscv/arcv-apex.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@
2424
UNSPEC_ARCV_APEX_VOID_SRC0_V
2525
UNSPEC_ARCV_APEX_VOID_SRC0_SRC1_V
2626
UNSPEC_ARCV_APEX_DEST
27+
UNSPEC_ARCV_APEX_DEST_V
2728
UNSPEC_ARCV_APEX_DEST_SRC0
29+
UNSPEC_ARCV_APEX_DEST_SRC0_V
2830
UNSPEC_ARCV_APEX_DEST_SRC0_SRC1
31+
UNSPEC_ARCV_APEX_DEST_SRC0_SRC1_V
2932
])
3033

3134
;; Used by "XD" insn. format: `insn`
@@ -93,6 +96,21 @@
9396
[(set_attr "type" "arith,arith")]
9497
)
9598

99+
;; Used by "XD" insn. format: `insn dest` volatile
100+
(define_insn "riscv_arcv_apex_dest_volatile"
101+
[(set (match_operand:SI 0 "register_operand" "=r")
102+
(unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "xAVpXD")]
103+
UNSPEC_ARCV_APEX_DEST_V))]
104+
""
105+
{
106+
const char *str = arcv_apex_get_insn_name (operands[1]);
107+
return xasprintf ("%s\t%s ; 'XD' `insn dest` volatile",
108+
str,
109+
reg_names[REGNO (operands[0])]);
110+
}
111+
[(set_attr "type" "arith")]
112+
)
113+
96114
;; Used by "XD" insn. format: `insn dest`
97115
(define_insn "riscv_arcv_apex_dest_ftype"
98116
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -108,6 +126,34 @@
108126
[(set_attr "type" "arith")]
109127
)
110128

129+
;; Used by "XI","XD" insn. format: `insn dest, src0` volatile
130+
(define_insn "riscv_arcv_apex_dest_src0_volatile"
131+
[(set (match_operand:SI 0 "register_operand" "=r,r")
132+
(unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "xAVpXI,xAVpXD")
133+
(match_operand:SI 2 "nonmemory_operand" "I,r")]
134+
UNSPEC_ARCV_APEX_DEST_SRC0_V))]
135+
""
136+
{
137+
const char *str = arcv_apex_get_insn_name (operands[1]);
138+
switch (which_alternative)
139+
{
140+
case 0:
141+
return xasprintf ("%si\t%s,%d ; 'XI' `insn des, src0` volatile",
142+
str,
143+
reg_names[REGNO (operands[0])],
144+
(int) INTVAL (operands[2]));
145+
case 1:
146+
return xasprintf ("%s\t%s,%s ; 'XD' `insn des, src0` volatile",
147+
str,
148+
reg_names[REGNO (operands[0])],
149+
reg_names[REGNO (operands[2])]);
150+
default:
151+
gcc_unreachable ();
152+
}
153+
}
154+
[(set_attr "type" "arith,arith")]
155+
)
156+
111157
;; Used by "XI","XD" insn. format: `insn dest, src0`
112158
(define_insn "riscv_arcv_apex_dest_ftype_src0"
113159
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -136,6 +182,43 @@
136182
[(set_attr "type" "arith,arith")]
137183
)
138184

185+
;; Used by "XS","XC","XD" insn. format: `insn dest, src0, imm/src1` volatile
186+
(define_insn "riscv_arcv_apex_dest_src0_src1_volatile"
187+
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
188+
(unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "xAVpXS,xAVpXC,xAVpXD")
189+
(match_operand:SI 2 "register_operand" "r,0,r")
190+
(match_operand:SI 3 "nonmemory_operand" "B8,I,r")]
191+
UNSPEC_ARCV_APEX_DEST_SRC0_SRC1_V))]
192+
""
193+
{
194+
const char *str = arcv_apex_get_insn_name (operands[1]);
195+
switch (which_alternative)
196+
{
197+
case 0:
198+
return xasprintf ("%si\t%s,%s,%d ; 'XS' `insn dest, src0, imm/src1` volatile",
199+
str,
200+
reg_names[REGNO (operands[0])],
201+
reg_names[REGNO (operands[2])],
202+
(int) INTVAL (operands[3]));
203+
case 1:
204+
return xasprintf ("%s%s\t%s,%s,%d ; 'XC' `insn dest/src0, imm` volatile",
205+
str,
206+
reg_names[REGNO (operands[0])],
207+
reg_names[REGNO (operands[2])],
208+
(int) INTVAL (operands[3]));
209+
case 2:
210+
return xasprintf ("%s\t%s,%s,%s ; 'XD' `insn dest, src0, imm/src1` volatile",
211+
str,
212+
reg_names[REGNO (operands[0])],
213+
reg_names[REGNO (operands[2])],
214+
reg_names[REGNO (operands[3])]);
215+
default:
216+
gcc_unreachable ();
217+
}
218+
}
219+
[(set_attr "type" "arith,arith,arith")]
220+
)
221+
139222
;; Used by "XS","XC","XD" insn. format: `insn dest, src0, imm/src1`
140223
(define_insn "riscv_arcv_apex_dest_ftype_src0_src1"
141224
[(set (match_operand:SI 0 "register_operand" "=r,r,r")

gcc/config/riscv/riscv-builtins.cc

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -650,9 +650,9 @@ arcv_apex_resolve_insn_format (unsigned int insn_format, unsigned int opcode)
650650
if ((insn_format & 0xF) != APEX_NONE)
651651
return insn_format;
652652

653-
/* Extract the operand flags (DEST, SRC0, SRC1) from bits 4–6.
653+
/* Extract the operand flags (DEST, SRC0, SRC1) from bits 5–7.
654654
These bits encode the operand signature used for format selection. */
655-
unsigned int insn_operands = insn_format >> 4;
655+
unsigned int insn_operands = insn_format >> 5;
656656

657657
/* Assign the most general format APEX_XD. If opcode does not permit,
658658
it will report an error at "arcv_apex_validate_insn_format". */
@@ -784,7 +784,7 @@ arcv_apex_validate_insn_format (const char* fn_name, unsigned int insn_format,
784784
that corresponds to the instruction variant used during RTL generation.
785785
786786
The operand layout is extracted by right-shifting out APEX_DEST and
787-
APEX_SRC flags (bits 4–6). The function matches the operand pattern
787+
APEX_SRC flags (bits 5–7). The function matches the operand pattern
788788
against predefined instruction codes for different instruction formats
789789
such as XI, XS, XC, and XD.
790790
@@ -793,7 +793,8 @@ arcv_apex_validate_insn_format (const char* fn_name, unsigned int insn_format,
793793
static enum insn_code
794794
arcv_apex_get_icode (unsigned insn_format)
795795
{
796-
unsigned int insn_operands = insn_format >> 4;
796+
unsigned int insn_operands = insn_format >> 5;
797+
bool is_volatile = insn_format & APEX_VOLATILE;
797798

798799
switch (insn_operands)
799800
{
@@ -811,15 +812,21 @@ arcv_apex_get_icode (unsigned insn_format)
811812

812813
/* Used by "XD" insn. format: `insn dest` */
813814
case APEX_DEST_FTYPE:
814-
return CODE_FOR_riscv_arcv_apex_dest_ftype;
815+
return is_volatile
816+
? CODE_FOR_riscv_arcv_apex_dest_ftype_v
817+
: CODE_FOR_riscv_arcv_apex_dest_ftype;
815818

816819
/* Used by "XI","XD" insn. format: `insn dest, src0` */
817820
case APEX_DEST_FTYPE_SRC0:
818-
return CODE_FOR_riscv_arcv_apex_dest_ftype_src0;
821+
return is_volatile
822+
? CODE_FOR_riscv_arcv_apex_dest_ftype_src0_v
823+
: CODE_FOR_riscv_arcv_apex_dest_ftype_src0;
819824

820825
/* Used by "XS","XC","XD" insn. format: `insn dest, src0, imm/src1` */
821826
case APEX_DEST_FTYPE_SRC0_SRC1:
822-
return CODE_FOR_riscv_arcv_apex_dest_ftype_src0_src1;
827+
return is_volatile
828+
? CODE_FOR_riscv_arcv_apex_dest_ftype_src0_src1_v
829+
: CODE_FOR_riscv_arcv_apex_dest_ftype_src0_src1;
823830

824831
default:
825832
/* If none is selected, the default is "CODE_FOR_nothing". */

gcc/config/riscv/riscv-c.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ arcv_apex_pragma_intrinsic (cpp_reader *)
274274
insn_formats |= APEX_XI;
275275
else if (strcmp (attribute, "XC") == 0)
276276
insn_formats |= APEX_XC;
277+
else if (strcmp (attribute, "side_effect") == 0)
278+
insn_formats |= APEX_VOLATILE;
277279
else if (strcmp (attribute, "opcode") == 0)
278280
{
279281
if (pragma_lex (&x) != CPP_EQ || pragma_lex (&x) != CPP_GREATER)

gcc/config/riscv/riscv.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9688,17 +9688,17 @@ riscv_asm_output_variant_cc (FILE *stream, const tree decl, const char *name)
96889688
more `.extInstruction` lines into the assembly output file, allowing the
96899689
assembler and disassembler to recognize the instruction variants.
96909690
9691-
The operand signature is encoded in bits 4–6 of `insn_format` and indicates
9691+
The operand signature is encoded in bits 5–7 of `insn_format` and indicates
96929692
the presence and types of operands such as destination, source0
96939693
and source1. */
96949694

96959695
void
96969696
arcv_apex_print_insn_section (const char *insn_name, int opcode,
96979697
unsigned int insn_format)
96989698
{
9699-
/* Extract the operand flags (DEST, SRC0, SRC1) from bits 4–6.
9699+
/* Extract the operand flags (DEST, SRC0, SRC1) from bits 5–7.
97009700
These bits encode the operand signature used for format selection. */
9701-
unsigned int insn_operands = insn_format >> 4;
9701+
unsigned int insn_operands = insn_format >> 5;
97029702

97039703
/* Print XD format line, adding operand info flags if absent. */
97049704
if (insn_format & APEX_XD)

gcc/config/riscv/riscv.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@ enum apex_insn_format {
7272
APEX_XS = 1 << 1,
7373
APEX_XI = 1 << 2,
7474
APEX_XC = 1 << 3,
75-
APEX_DEST = 1 << 4,
76-
APEX_SRC0 = 1 << 5,
77-
APEX_SRC1 = 1 << 6,
75+
APEX_VOLATILE = 1 << 4,
76+
APEX_DEST = 1 << 5,
77+
APEX_SRC0 = 1 << 6,
78+
APEX_SRC1 = 1 << 7,
7879
};
7980

8081
#endif /* ! RISCV_APEX */

0 commit comments

Comments
 (0)