Revision | 4609190b5f7f68a5e2a8738029594f45a062d4c9 (tree) |
---|---|
Time | 2017-09-06 23:24:46 |
Author | Richard Henderson <rth@twid...> |
Commiter | Richard Henderson |
tcg/s390: Use slbgr for setcond le and leu
Acked-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
@@ -1084,11 +1084,20 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond, | ||
1084 | 1084 | |
1085 | 1085 | have_loc = (s390_facilities & FACILITY_LOAD_ON_COND) != 0; |
1086 | 1086 | |
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: | |
1088 | 1089 | 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 | + | |
1089 | 1099 | case TCG_COND_GTU: |
1090 | 1100 | case TCG_COND_GT: |
1091 | - do_greater: | |
1092 | 1101 | /* The result of a compare has CC=2 for GT and CC=3 unused. |
1093 | 1102 | ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */ |
1094 | 1103 | tgen_cmp(s, type, cond, c1, c2, c2const, true); |
@@ -1096,49 +1105,33 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond, | ||
1096 | 1105 | tcg_out_insn(s, RRE, ALCGR, dest, dest); |
1097 | 1106 | return; |
1098 | 1107 | |
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; | |
1119 | 1112 | } 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; | |
1126 | 1114 | } |
1127 | - tcg_out_movi(s, TCG_TYPE_I64, dest, 0); | |
1128 | - tcg_out_insn(s, RRE, ALCGR, dest, dest); | |
1129 | - return; | |
1115 | + /* fallthru */ | |
1130 | 1116 | |
1131 | 1117 | 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: | |
1136 | 1128 | case TCG_COND_LTU: |
1137 | 1129 | 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. */ | |
1139 | 1132 | if (c2const) { |
1140 | 1133 | if (have_loc) { |
1141 | - goto do_loc; | |
1134 | + break; | |
1142 | 1135 | } |
1143 | 1136 | tcg_out_movi(s, type, TCG_TMP0, c2); |
1144 | 1137 | c2 = c1; |
@@ -1149,51 +1142,25 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond, | ||
1149 | 1142 | c1 = c2; |
1150 | 1143 | c2 = t; |
1151 | 1144 | } |
1152 | - if (cond == TCG_COND_LEU) { | |
1153 | - goto do_geu; | |
1154 | - } | |
1155 | 1145 | 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; | |
1179 | 1147 | |
1180 | 1148 | default: |
1181 | - break; | |
1149 | + g_assert_not_reached(); | |
1182 | 1150 | } |
1183 | 1151 | |
1184 | 1152 | 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 | + } | |
1197 | 1164 | } |
1198 | 1165 | |
1199 | 1166 | static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest, |