Skip to content

Commit 3c8fb51

Browse files
Claudiu Zissulescuartemiy-volkov
authored andcommitted
arc64: Add patterns matching dmacwh[u], dmpywh[u] and dmach
1 parent cf241be commit 3c8fb51

File tree

3 files changed

+221
-0
lines changed

3 files changed

+221
-0
lines changed

gcc/config/arc64/arc64.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,7 @@ get_arc64_condition_code (rtx comparison)
12941294
's': Scalled immediate.
12951295
'S': Scalled immediate, to be used in pair with 's'.
12961296
'N': Negative immediate, to be used in pair with 's'.
1297+
'H': 2x16b vector immediate, hi lane is zero.
12971298
*/
12981299

12991300
static void
@@ -1400,6 +1401,17 @@ arc64_print_operand (FILE *file, rtx x, int code)
14001401
}
14011402
break;
14021403

1404+
case 'H':
1405+
if (!CONST_INT_P (x))
1406+
{
1407+
output_operand_lossage ("invalid operand for %%H code");
1408+
return;
1409+
}
1410+
ival = INTVAL (x);
1411+
ival &= 0xffffULL;
1412+
fprintf (file, "0x%08" PRIx32, (uint32_t) ival);
1413+
break;
1414+
14031415
case 'm':
14041416
fputs (arc_condition_codes[get_arc64_condition_code (x)], file);
14051417
break;
@@ -2564,6 +2576,11 @@ arc64_reorg (void)
25642576
mode = E_SImode;
25652577
break;
25662578

2579+
case CODE_FOR_dmach0:
2580+
icode = CODE_FOR_dmach;
2581+
mode = E_HImode;
2582+
break;
2583+
25672584
default:
25682585
continue;
25692586
}
@@ -2595,6 +2612,7 @@ arc64_reorg (void)
25952612
op2 = XEXP (XEXP (XEXP (tmp, 0), 1), 0);
25962613
break;
25972614

2615+
case CODE_FOR_dmach0:
25982616
case CODE_FOR_macsi0:
25992617
tmp = SET_SRC (PATTERN (insn));
26002618
op1 = XEXP (XEXP (tmp, 0), 0);

gcc/config/arc64/arc64.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@
138138
ARC64_UNSPEC_QMPYH
139139
ARC64_UNSPEC_QMACH
140140
ARC64_UNSPEC_DMPYWH
141+
ARC64_UNSPEC_DMPYWHU
142+
ARC64_UNSPEC_DMACWH
143+
ARC64_UNSPEC_DMACWHU
141144
ARC64_UNSPEC_VPACK4HL
142145
ARC64_UNSPEC_VPACK4HM
143146
ARC64_UNSPEC_VPACK2WL

gcc/config/arc64/arith.md

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,206 @@
10931093
[(set (reg:SI R58_REGNUM)
10941094
(mult:SI (ANY_EXTEND:SI (match_dup 1)) (match_dup 2)))])
10951095

1096+
;; Another combiner pattern (observed in rgbyiq01)
1097+
(define_insn_and_split "dmpywhu"
1098+
[(set (match_operand:SI 0 "register_operand" "=r")
1099+
(plus:SI
1100+
(mult:SI (match_operand:SI 1 "register_operand" "r")
1101+
(match_operand 2 "unsign_immediate_operand" "i"))
1102+
(mult:SI (match_operand:SI 3"register_operand" "r")
1103+
(match_operand 4 "unsign_immediate_operand" "i"))))
1104+
(clobber (reg:DI R58_REGNUM))]
1105+
"TARGET_SIMD"
1106+
"#"
1107+
"&& reload_completed"
1108+
[(parallel [(set (match_dup 0)
1109+
(unspec:SI [(match_dup 5) (match_dup 2)]
1110+
ARC64_UNSPEC_DMPYWHU))
1111+
(clobber (reg:DI R58_REGNUM))])]
1112+
{
1113+
operands[5] = gen_lowpart (DImode, operands[0]);
1114+
emit_insn (gen_pack2silo (operands[5], operands[3], operands[1]));
1115+
operands[2] = GEN_INT ((INTVAL (operands[2]) << 16) + INTVAL (operands[4]));
1116+
}
1117+
[(set_attr "length" "8")
1118+
(set_attr "type" "dmpywh")])
1119+
1120+
(define_insn "dmpywhu0"
1121+
[(set (match_operand:SI 0 "register_operand" "=accum,r")
1122+
(unspec:SI [(match_operand:DI 1 "register_operand" "r,r")
1123+
(match_operand 2 "immediate_operand" "i,i")]
1124+
ARC64_UNSPEC_DMPYWHU))
1125+
(clobber (reg:DI R58_REGNUM))]
1126+
"TARGET_SIMD"
1127+
"@
1128+
dmpywhu\\t0,%1,%2@u32
1129+
dmpywhu\\t%0,%1,%2@u32"
1130+
[(set_attr "length" "8")
1131+
(set_attr "type" "dmpywh")])
1132+
1133+
(define_insn_and_split "dmpywh"
1134+
[(set (match_operand:SI 0 "register_operand" "=r")
1135+
(plus:SI
1136+
(mult:SI (match_operand:SI 1 "register_operand" "r")
1137+
(match_operand 2 "short_immediate_operand" "i"))
1138+
(mult:SI (match_operand:SI 3"register_operand" "r")
1139+
(match_operand 4 "short_immediate_operand" "i"))))
1140+
(clobber (reg:DI R58_REGNUM))]
1141+
"TARGET_SIMD"
1142+
"#"
1143+
"&& reload_completed"
1144+
[(parallel [(set (match_dup 0)
1145+
(unspec:SI [(match_dup 5) (match_dup 2)]
1146+
ARC64_UNSPEC_DMPYWH))
1147+
(clobber (reg:SI R58_REGNUM))])]
1148+
{
1149+
operands[5] = gen_lowpart (DImode, operands[0]);
1150+
emit_insn (gen_pack2silo (operands[5], operands[3], operands[1]));
1151+
operands[2] = GEN_INT ((INTVAL (operands[2]) << 16) +
1152+
(INTVAL (operands[4]) & 0xffff));
1153+
}
1154+
[(set_attr "length" "8")
1155+
(set_attr "type" "dmpywh")])
1156+
1157+
(define_insn "dmpywh0"
1158+
[(set (match_operand:SI 2 "register_operand" "=accum,r")
1159+
(unspec:SI [(match_operand:DI 0 "register_operand" "r,r")
1160+
(match_operand 1 "immediate_operand" "i,i")]
1161+
ARC64_UNSPEC_DMPYWH))
1162+
(clobber (reg:SI R58_REGNUM))]
1163+
"TARGET_SIMD"
1164+
"@
1165+
dmpywh\\t0,%0,%1@u32
1166+
dmpywh\\t%2,%0,%1@u32"
1167+
[(set_attr "length" "8")
1168+
(set_attr "type" "dmpywh")])
1169+
1170+
;; dmach combine pattern used to implement 16b MAC patterns. Extra
1171+
;; care needs to be taken when dealing with immediates which needs to
1172+
;; set the higher 16b to zero. I.e. we cannot use safely U6 or S12
1173+
;; instruction variants.
1174+
(define_insn_and_split "dmach"
1175+
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
1176+
(plus:HI
1177+
(mult:HI (match_operand:HI 1 "register_operand" "%r,r,r")
1178+
(match_operand:HI 2 "nonmemory_operand" "r,i,*ri"))
1179+
(match_operand:HI 3 "nonmemory_operand" "accum,accum,*ri")))
1180+
(clobber (reg:DI R58_REGNUM))]
1181+
"TARGET_SIMD"
1182+
"@
1183+
dmach\\t%0,%1,%2
1184+
dmach\\t%0,%1,%H2@u32
1185+
#"
1186+
"&& reload_completed
1187+
&& (CONST_INT_P (operands[3]) || (REGNO (operands[3]) != R58_REGNUM))"
1188+
[(set (reg:HI R58_REGNUM) (match_dup 3))
1189+
(set (reg:HI R58_REGNUM)
1190+
(plus:HI (mult:HI (match_dup 1) (match_dup 2)) (reg:HI R58_REGNUM)))
1191+
(set (match_dup 0) (reg:HI R58_REGNUM))]
1192+
""
1193+
[(set_attr "length" "4,8,8")
1194+
(set_attr "type" "mac")])
1195+
1196+
(define_insn "dmach0"
1197+
[(set (reg:HI R58_REGNUM)
1198+
(plus:HI (mult:HI (match_operand:HI 0 "register_operand" "%r,r")
1199+
(match_operand:HI 1 "nonmemory_operand" "r,i"))
1200+
(reg:HI R58_REGNUM)))]
1201+
"TARGET_SIMD"
1202+
"@
1203+
dmach\\t0,%0,%1
1204+
dmach\\t0,%0,%H1@u32"
1205+
[(set_attr "length" "4,8")
1206+
(set_attr "type" "mac")])
1207+
1208+
;; macwh combine pattern
1209+
;; FIXME! the last move instruction needs to be combined back
1210+
;; into dmacwh(u) insn
1211+
(define_insn_and_split "dmacwh"
1212+
[(set (match_operand:SI 0 "register_operand" "=r")
1213+
(plus:SI
1214+
(plus:SI
1215+
(mult:SI (match_operand:SI 1 "register_operand" "r")
1216+
(match_operand 2 "short_immediate_operand" "i"))
1217+
(mult:SI (match_operand:SI 3 "register_operand" "r")
1218+
(match_operand 4 "short_immediate_operand" "i")))
1219+
(match_operand:SI 5 "nonmemory_operand" "ri")))
1220+
(clobber (reg:DI R58_REGNUM))]
1221+
"TARGET_SIMD"
1222+
"#"
1223+
"&& reload_completed"
1224+
[(set (reg:SI R58_REGNUM)
1225+
(unspec:SI [(match_dup 6) (match_dup 2) (reg:SI R58_REGNUM)]
1226+
ARC64_UNSPEC_DMACWH))
1227+
(set (match_dup 0) (reg:SI R58_REGNUM))]
1228+
{
1229+
emit_move_insn (gen_rtx_REG (SImode, R58_REGNUM), operands[5]);
1230+
operands[6] = gen_lowpart (DImode, operands[0]);
1231+
emit_insn (gen_pack2silo (operands[6], operands[3], operands[1]));
1232+
operands[2] = GEN_INT ((INTVAL (operands[2]) << 16)
1233+
+ (INTVAL (operands[4]) & 0xffff));
1234+
}
1235+
[(set_attr "length" "8")
1236+
(set_attr "type" "mac")])
1237+
1238+
(define_insn "pack2silo"
1239+
[(set (match_operand:DI 0 "register_operand" "=r")
1240+
(unspec:DI [(match_operand:SI 1 "register_operand" "r")
1241+
(match_operand:SI 2 "register_operand" "r")]
1242+
ARC64_UNSPEC_VPACK2WL))]
1243+
""
1244+
"vpack2wl\\t%0,%1,%2"
1245+
[(set_attr "length" "4")
1246+
(set_attr "type" "vpack")])
1247+
1248+
(define_insn "dmacwh0"
1249+
[(set (reg:SI R58_REGNUM)
1250+
(unspec:SI [(match_operand:DI 0 "register_operand" "r")
1251+
(match_operand 1 "immediate_operand" "i")
1252+
(reg:SI R58_REGNUM)]
1253+
ARC64_UNSPEC_DMACWH))]
1254+
"TARGET_SIMD"
1255+
"dmacwh\\t0,%0,%1@u32"
1256+
[(set_attr "length" "8")
1257+
(set_attr "type" "mac")])
1258+
1259+
(define_insn_and_split "dmacwhu"
1260+
[(set (match_operand:SI 0 "register_operand" "=r")
1261+
(plus:SI
1262+
(plus:SI
1263+
(mult:SI (match_operand:SI 1 "register_operand" "r")
1264+
(match_operand 2 "unsign_immediate_operand" "i"))
1265+
(mult:SI (match_operand:SI 3 "register_operand" "r")
1266+
(match_operand 4 "unsign_immediate_operand" "i")))
1267+
(match_operand:SI 5 "nonmemory_operand" "ri")))
1268+
(clobber (reg:DI R58_REGNUM))]
1269+
"TARGET_SIMD"
1270+
"#"
1271+
"&& reload_completed"
1272+
[(set (reg:SI R58_REGNUM)
1273+
(unspec:SI [(match_dup 6) (match_dup 2) (reg:SI R58_REGNUM)]
1274+
ARC64_UNSPEC_DMACWHU))
1275+
(set (match_dup 0) (reg:SI R58_REGNUM))]
1276+
{
1277+
emit_move_insn (gen_rtx_REG (SImode, R58_REGNUM), operands[5]);
1278+
operands[6] = gen_lowpart (DImode, operands[0]);
1279+
emit_insn (gen_pack2silo (operands[6], operands[3], operands[1]));
1280+
operands[2] = GEN_INT ((INTVAL (operands[2]) << 16) + INTVAL (operands[4]));
1281+
}
1282+
[(set_attr "length" "8")
1283+
(set_attr "type" "mac")])
1284+
1285+
(define_insn "dmacwhu0"
1286+
[(set (reg:SI R58_REGNUM)
1287+
(unspec:SI [(match_operand:DI 0 "register_operand" "r")
1288+
(match_operand 1 "immediate_operand" "i")
1289+
(reg:SI R58_REGNUM)]
1290+
ARC64_UNSPEC_DMACWHU))]
1291+
"TARGET_SIMD"
1292+
"dmacwhu\\t0,%0,%1@u32"
1293+
[(set_attr "length" "8")
1294+
(set_attr "type" "mac")])
1295+
10961296
;; -------------------------------------------------------------------
10971297
;; Integer SIMD instructions
10981298
;; -------------------------------------------------------------------

0 commit comments

Comments
 (0)