aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorAndrew Stubbs <ams@codesourcery.com>2020-05-13 16:24:12 +0100
committerAndrew Stubbs <ams@codesourcery.com>2020-10-07 12:51:51 +0100
commit76136f7f0ce8f4e27ac194af6429d378360b7b41 (patch)
tree225eb556673ffaf7d4a9dd23e40020fd2f290219 /gcc/config
parentd22eecf8754cc22c7a19bfab9834f6d918c7838d (diff)
downloadgcc-76136f7f0ce8f4e27ac194af6429d378360b7b41.zip
gcc-76136f7f0ce8f4e27ac194af6429d378360b7b41.tar.gz
gcc-76136f7f0ce8f4e27ac194af6429d378360b7b41.tar.bz2
amdgcn: Use scalar instructions for addptrdi3
Allow addptr to use SPGRs as well as VGPRs for pointers. This ought to prevent some unnecessary copying back and forth. gcc/ChangeLog: * config/gcn/gcn.md (unspec): Add UNSPEC_ADDPTR. (addptrdi3): Add SGPR alternative.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/gcn/gcn.md43
1 files changed, 31 insertions, 12 deletions
diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md
index 0e73fea..763e770 100644
--- a/gcc/config/gcn/gcn.md
+++ b/gcc/config/gcn/gcn.md
@@ -67,6 +67,7 @@
UNSPECV_ICACHE_INV])
(define_c_enum "unspec" [
+ UNSPEC_ADDPTR
UNSPEC_VECTOR
UNSPEC_BPERMUTE
UNSPEC_SGPRBASE
@@ -1219,29 +1220,47 @@
; "addptr" is the same as "add" except that it must not write to VCC or SCC
; as a side-effect. Unfortunately GCN does not have a suitable instruction
-; for this, so we use a custom VOP3 add with CC_SAVE_REG as a temp.
-; Note that it is not safe to save/clobber/restore SCC because doing so will
-; break data-flow analysis, so this must use vector registers.
+; for this, so we use CC_SAVE_REG as a temp.
+; Note that it is not safe to save/clobber/restore as separate insns because
+; doing so will break data-flow analysis, so this must use multiple
+; instructions in one insn.
;
; The "v0" should be just "v", but somehow the "0" helps LRA not loop forever
; on testcase pr54713-2.c with -O0. It's only an optimization hint anyway.
+;
+; The SGPR alternative is preferred as it is typically used with mov_sgprbase.
(define_insn "addptrdi3"
- [(set (match_operand:DI 0 "register_operand" "= v")
- (plus:DI (match_operand:DI 1 "register_operand" " v0")
- (match_operand:DI 2 "nonmemory_operand" "vDA")))]
+ [(set (match_operand:DI 0 "register_operand" "= v, Sg")
+ (unspec:DI [
+ (plus:DI (match_operand:DI 1 "register_operand" "^v0,Sg0")
+ (match_operand:DI 2 "nonmemory_operand" "vDA,SgDB"))]
+ UNSPEC_ADDPTR))]
""
{
- rtx new_operands[4] = { operands[0], operands[1], operands[2],
- gen_rtx_REG (DImode, CC_SAVE_REG) };
+ if (which_alternative == 0)
+ {
+ rtx new_operands[4] = { operands[0], operands[1], operands[2],
+ gen_rtx_REG (DImode, CC_SAVE_REG) };
- output_asm_insn ("v_add%^_u32 %L0, %3, %L2, %L1", new_operands);
- output_asm_insn ("v_addc%^_u32 %H0, %3, %H2, %H1, %3", new_operands);
+ output_asm_insn ("v_add%^_u32\t%L0, %3, %L2, %L1", new_operands);
+ output_asm_insn ("v_addc%^_u32\t%H0, %3, %H2, %H1, %3", new_operands);
+ }
+ else
+ {
+ rtx new_operands[4] = { operands[0], operands[1], operands[2],
+ gen_rtx_REG (BImode, CC_SAVE_REG) };
+
+ output_asm_insn ("s_mov_b32\t%3, scc", new_operands);
+ output_asm_insn ("s_add_u32\t%L0, %L1, %L2", new_operands);
+ output_asm_insn ("s_addc_u32\t%H0, %H1, %H2", new_operands);
+ output_asm_insn ("s_cmpk_lg_u32\t%3, 0", new_operands);
+ }
return "";
}
- [(set_attr "type" "vmult")
- (set_attr "length" "16")])
+ [(set_attr "type" "vmult,mult")
+ (set_attr "length" "16,24")])
;; }}}
;; {{{ ALU special cases: Minus