• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision4609190b5f7f68a5e2a8738029594f45a062d4c9 (tree)
Time2017-09-06 23:24:46
AuthorRichard Henderson <rth@twid...>
CommiterRichard Henderson

Log Message

tcg/s390: Use slbgr for setcond le and leu

Acked-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>

Change Summary

Incremental Difference

--- a/tcg/s390/tcg-target.inc.c
+++ b/tcg/s390/tcg-target.inc.c
@@ -1084,11 +1084,20 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
10841084
10851085 have_loc = (s390_facilities & FACILITY_LOAD_ON_COND) != 0;
10861086
1087- /* For HAVE_LOC, only the path through do_greater is smaller. */
1087+ /* For HAVE_LOC, only the paths through GTU/GT/LEU/LE are smaller. */
1088+ restart:
10881089 switch (cond) {
1090+ case TCG_COND_NE:
1091+ /* X != 0 is X > 0. */
1092+ if (c2const && c2 == 0) {
1093+ cond = TCG_COND_GTU;
1094+ } else {
1095+ break;
1096+ }
1097+ /* fallthru */
1098+
10891099 case TCG_COND_GTU:
10901100 case TCG_COND_GT:
1091- do_greater:
10921101 /* The result of a compare has CC=2 for GT and CC=3 unused.
10931102 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
10941103 tgen_cmp(s, type, cond, c1, c2, c2const, true);
@@ -1096,49 +1105,33 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
10961105 tcg_out_insn(s, RRE, ALCGR, dest, dest);
10971106 return;
10981107
1099- case TCG_COND_GEU:
1100- if (have_loc) {
1101- goto do_loc;
1102- }
1103- do_geu:
1104- /* We need "real" carry semantics, so use SUBTRACT LOGICAL
1105- instead of COMPARE LOGICAL. This may need an extra move. */
1106- if (c2const) {
1107- tcg_out_mov(s, type, TCG_TMP0, c1);
1108- if (type == TCG_TYPE_I32) {
1109- tcg_out_insn(s, RIL, SLFI, TCG_TMP0, c2);
1110- } else {
1111- tcg_out_insn(s, RIL, SLGFI, TCG_TMP0, c2);
1112- }
1113- } else if (s390_facilities & FACILITY_DISTINCT_OPS) {
1114- if (type == TCG_TYPE_I32) {
1115- tcg_out_insn(s, RRF, SLRK, TCG_TMP0, c1, c2);
1116- } else {
1117- tcg_out_insn(s, RRF, SLGRK, TCG_TMP0, c1, c2);
1118- }
1108+ case TCG_COND_EQ:
1109+ /* X == 0 is X <= 0. */
1110+ if (c2const && c2 == 0) {
1111+ cond = TCG_COND_LEU;
11191112 } else {
1120- tcg_out_mov(s, type, TCG_TMP0, c1);
1121- if (type == TCG_TYPE_I32) {
1122- tcg_out_insn(s, RR, SLR, TCG_TMP0, c2);
1123- } else {
1124- tcg_out_insn(s, RRE, SLGR, TCG_TMP0, c2);
1125- }
1113+ break;
11261114 }
1127- tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1128- tcg_out_insn(s, RRE, ALCGR, dest, dest);
1129- return;
1115+ /* fallthru */
11301116
11311117 case TCG_COND_LEU:
1132- if (have_loc) {
1133- goto do_loc;
1134- }
1135- /* fallthru */
1118+ case TCG_COND_LE:
1119+ /* As above, but we're looking for borrow, or !carry.
1120+ The second insn computes d - d - borrow, or -1 for true
1121+ and 0 for false. So we must mask to 1 bit afterward. */
1122+ tgen_cmp(s, type, cond, c1, c2, c2const, true);
1123+ tcg_out_insn(s, RRE, SLBGR, dest, dest);
1124+ tgen_andi(s, type, dest, 1);
1125+ return;
1126+
1127+ case TCG_COND_GEU:
11361128 case TCG_COND_LTU:
11371129 case TCG_COND_LT:
1138- /* Swap operands so that we can use GEU/GTU/GT. */
1130+ case TCG_COND_GE:
1131+ /* Swap operands so that we can use LEU/GTU/GT/LE. */
11391132 if (c2const) {
11401133 if (have_loc) {
1141- goto do_loc;
1134+ break;
11421135 }
11431136 tcg_out_movi(s, type, TCG_TMP0, c2);
11441137 c2 = c1;
@@ -1149,51 +1142,25 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
11491142 c1 = c2;
11501143 c2 = t;
11511144 }
1152- if (cond == TCG_COND_LEU) {
1153- goto do_geu;
1154- }
11551145 cond = tcg_swap_cond(cond);
1156- goto do_greater;
1157-
1158- case TCG_COND_NE:
1159- /* X != 0 is X > 0. */
1160- if (c2const && c2 == 0) {
1161- cond = TCG_COND_GTU;
1162- goto do_greater;
1163- }
1164- break;
1165-
1166- case TCG_COND_EQ:
1167- if (have_loc) {
1168- goto do_loc;
1169- }
1170- /* X == 0 is X <= 0 is 0 >= X. */
1171- if (c2const && c2 == 0) {
1172- tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 0);
1173- c2 = c1;
1174- c2const = 0;
1175- c1 = TCG_TMP0;
1176- goto do_geu;
1177- }
1178- break;
1146+ goto restart;
11791147
11801148 default:
1181- break;
1149+ g_assert_not_reached();
11821150 }
11831151
11841152 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1185- /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1186- tcg_out_movi(s, type, dest, 1);
1187- tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1188- tcg_out_movi(s, type, dest, 0);
1189- return;
1190-
1191- do_loc:
1192- cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1193- /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1194- tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1195- tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1196- tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);
1153+ if (have_loc) {
1154+ /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1155+ tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1156+ tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1157+ tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);
1158+ } else {
1159+ /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1160+ tcg_out_movi(s, type, dest, 1);
1161+ tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1162+ tcg_out_movi(s, type, dest, 0);
1163+ }
11971164 }
11981165
11991166 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,