Skip to content

Commit c932863

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 99fb5bf commit c932863

File tree

5 files changed

+103
-13
lines changed

5 files changed

+103
-13
lines changed

gcc/config/riscv/arcv-apex.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,21 @@
9393
[(set_attr "type" "arith,arith")]
9494
)
9595

96+
;; Used by "XD" insn. format: `insn dest` volatile
97+
(define_insn "riscv_arcv_apex_dest_volatile"
98+
[(set (match_operand:SI 0 "register_operand" "=r")
99+
(unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "xAVpXD")]
100+
UNSPEC_ARCV_APEX_DEST))]
101+
""
102+
{
103+
const char *str = arcv_apex_get_insn_name (operands[1]);
104+
return xasprintf ("%s\t%s ; 'XD' `insn dest` volatile",
105+
str,
106+
reg_names[REGNO (operands[0])]);
107+
}
108+
[(set_attr "type" "arith")]
109+
)
110+
96111
;; Used by "XD" insn. format: `insn dest`
97112
(define_insn "riscv_arcv_apex_dest_ftype"
98113
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -108,6 +123,34 @@
108123
[(set_attr "type" "arith")]
109124
)
110125

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

182+
;; Used by "XS","XC","XD" insn. format: `insn dest, src0, imm/src1` volatile
183+
(define_insn "riscv_arcv_apex_dest_src0_src1_volatile"
184+
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
185+
(unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "xAVpXS,xAVpXC,xAVpXD")
186+
(match_operand:SI 2 "register_operand" "r,0,r")
187+
(match_operand:SI 3 "nonmemory_operand" "B8,I,r")]
188+
UNSPEC_ARCV_APEX_DEST_SRC0_SRC1))]
189+
""
190+
{
191+
const char *str = arcv_apex_get_insn_name (operands[1]);
192+
switch (which_alternative)
193+
{
194+
case 0:
195+
return xasprintf ("%si\t%s,%s,%d ; 'XS' `insn dest, src0, imm/src1` volatile",
196+
str,
197+
reg_names[REGNO (operands[0])],
198+
reg_names[REGNO (operands[2])],
199+
(int) INTVAL (operands[3]));
200+
case 1:
201+
return xasprintf ("%s%s\t%s,%s,%d ; 'XC' `insn dest/src0, imm` volatile",
202+
str,
203+
reg_names[REGNO (operands[0])],
204+
reg_names[REGNO (operands[2])],
205+
(int) INTVAL (operands[3]));
206+
case 2:
207+
return xasprintf ("%s\t%s,%s,%s ; 'XD' `insn dest, src0, imm/src1` volatile",
208+
str,
209+
reg_names[REGNO (operands[0])],
210+
reg_names[REGNO (operands[2])],
211+
reg_names[REGNO (operands[3])]);
212+
default:
213+
gcc_unreachable ();
214+
}
215+
}
216+
[(set_attr "type" "arith,arith,arith")]
217+
)
218+
139219
;; Used by "XS","XC","XD" insn. format: `insn dest, src0, imm/src1`
140220
(define_insn "riscv_arcv_apex_dest_ftype_src0_src1"
141221
[(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
@@ -267,6 +267,8 @@ arcv_apex_pragma_intrinsic (cpp_reader *)
267267
insn_formats |= APEX_XI;
268268
else if (strcmp (attribute, "XC") == 0)
269269
insn_formats |= APEX_XC;
270+
else if (strcmp (attribute, "side_effect") == 0)
271+
insn_formats |= APEX_VOLATILE;
270272
else if (strcmp (attribute, "opcode") == 0)
271273
{
272274
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)