@@ -381,6 +381,42 @@ static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
}
}
+static void tgen32_cmp(TCGContext *s, TCGCond c, TCGReg r1, TCGReg r2)
+{
+ if (c > TCG_COND_GT) {
+ /* unsigned */
+ tcg_out_insn(s, RR, CLR, r1, r2);
+ } else {
+ /* signed */
+ tcg_out_insn(s, RR, CR, r1, r2);
+ }
+}
+
+static void tgen64_cmp(TCGContext *s, TCGCond c, TCGReg r1, TCGReg r2)
+{
+ if (c > TCG_COND_GT) {
+ /* unsigned */
+ tcg_out_insn(s, RRE, CLGR, r1, r2);
+ } else {
+ /* signed */
+ tcg_out_insn(s, RRE, CGR, r1, r2);
+ }
+}
+
+static void tgen_setcond(TCGContext *s, TCGType type, TCGCond c,
+ TCGReg dest, TCGReg r1, TCGReg r2)
+{
+ if (type == TCG_TYPE_I32) {
+ tgen32_cmp(s, c, r1, r2);
+ } else {
+ tgen64_cmp(s, c, r1, r2);
+ }
+ /* Emit: r1 = 1; if (cc) goto over; r1 = 0; over: */
+ tcg_out_movi(s, type, dest, 1);
+ tcg_out_insn(s, RI, BRC, tcg_cond_to_s390_cond[c], (4 + 4) >> 1);
+ tcg_out_movi(s, type, dest, 0);
+}
+
#if defined(CONFIG_SOFTMMU)
static void tcg_prepare_qemu_ldst(TCGContext* s, int data_reg, int addr_reg,
int mem_index, int opc,
@@ -958,27 +994,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_brcond_i64:
- if (args[2] > TCG_COND_GT) {
- /* unsigned */
- /* clgr %ra0, %ra1 */
- tcg_out_insn(s, RRE, CLGR, args[0], args[1]);
- } else {
- /* signed */
- /* cgr %ra0, %ra1 */
- tcg_out_insn(s, RRE, CGR, args[0], args[1]);
- }
+ tgen64_cmp(s, args[2], args[0], args[1]);
goto do_brcond;
-
case INDEX_op_brcond_i32:
- if (args[2] > TCG_COND_GT) {
- /* unsigned */
- /* clr %ra0, %ra1 */
- tcg_out_insn(s, RR, CLR, args[0], args[1]);
- } else {
- /* signed */
- /* cr %ra0, %ra1 */
- tcg_out_insn(s, RR, CR, args[0], args[1]);
- }
+ tgen32_cmp(s, args[2], args[0], args[1]);
do_brcond:
l = &s->labels[args[3]];
if (l->has_value) {
@@ -993,6 +1012,13 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_insn(s, RR, BCR, tcg_cond_to_s390_cond[args[2]], TCG_REG_R13);
break;
+ case INDEX_op_setcond_i32:
+ tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2]);
+ break;
+ case INDEX_op_setcond_i64:
+ tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2]);
+ break;
+
case INDEX_op_qemu_ld8u:
tcg_out_qemu_ld(s, args, LD_UINT8);
break;
@@ -1083,6 +1109,7 @@ static const TCGTargetOpDef s390_op_defs[] = {
{ INDEX_op_sar_i32, { "r", "0", "Ri" } },
{ INDEX_op_brcond_i32, { "r", "r" } },
+ { INDEX_op_setcond_i32, { "r", "r", "r" } },
{ INDEX_op_qemu_ld8u, { "r", "L" } },
{ INDEX_op_qemu_ld8s, { "r", "L" } },
@@ -1129,6 +1156,7 @@ static const TCGTargetOpDef s390_op_defs[] = {
{ INDEX_op_sar_i64, { "r", "r", "Ri" } },
{ INDEX_op_brcond_i64, { "r", "r" } },
+ { INDEX_op_setcond_i64, { "r", "r", "r" } },
#endif
{ -1 },
Signed-off-by: Richard Henderson <rth@twiddle.net> --- tcg/s390/tcg-target.c | 66 ++++++++++++++++++++++++++++++++++-------------- 1 files changed, 47 insertions(+), 19 deletions(-)