static void test_uncond_jump () { rtx_insn *label = gen_label_rtx (); rtx jump_pat = gen_rtx_SET (pc_rtx, gen_rtx_LABEL_REF (VOIDmode, label)); ASSERT_EQ (SET, jump_pat->code); ASSERT_EQ (LABEL_REF, SET_SRC (jump_pat)->code); ASSERT_EQ (label, label_ref_label (SET_SRC (jump_pat))); ASSERT_EQ (PC, SET_DEST (jump_pat)->code); verify_print_pattern ("pc=L0", jump_pat); ASSERT_RTL_DUMP_EQ ("(set (pc)\n" " (label_ref 0))", jump_pat); rtx_insn *jump_insn = emit_jump_insn (jump_pat); ASSERT_FALSE (any_condjump_p (jump_insn)); ASSERT_TRUE (any_uncondjump_p (jump_insn)); ASSERT_TRUE (pc_set (jump_insn)); ASSERT_TRUE (simplejump_p (jump_insn)); ASSERT_TRUE (onlyjump_p (jump_insn)); ASSERT_TRUE (control_flow_insn_p (jump_insn)); ASSERT_RTL_DUMP_EQ ("(cjump_insn 1 (set (pc)\n" " (label_ref 0)))\n", jump_insn); }
static void test_single_set () { /* A label is not a SET. */ ASSERT_EQ (NULL_RTX, single_set (gen_label_rtx ())); /* An unconditional jump insn is a single SET. */ rtx set_pc = gen_rtx_SET (pc_rtx, gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ())); rtx_insn *jump_insn = emit_jump_insn (set_pc); ASSERT_EQ (set_pc, single_set (jump_insn)); /* etc */ }
static void gen_int_relational (enum rtx_code code, rtx result, rtx cmp0, rtx cmp1, rtx destination) { machine_mode mode; int branch_p; mode = GET_MODE (cmp0); if (mode == VOIDmode) mode = GET_MODE (cmp1); /* Is this a branch or compare. */ branch_p = (destination != 0); /* Instruction set doesn't support LE or LT, so swap operands and use GE, GT. */ switch (code) { case LE: case LT: case LEU: case LTU: { rtx temp; code = swap_condition (code); temp = cmp0; cmp0 = cmp1; cmp1 = temp; break; } default: break; } if (branch_p) { rtx insn, cond, label; /* Operands must be in registers. */ if (!register_operand (cmp0, mode)) cmp0 = force_reg (mode, cmp0); if (!register_operand (cmp1, mode)) cmp1 = force_reg (mode, cmp1); /* Generate conditional branch instruction. */ cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1); label = gen_rtx_LABEL_REF (VOIDmode, destination); insn = gen_rtx_SET (pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx)); emit_jump_insn (insn); } else { /* We can't have const_ints in cmp0, other than 0. */ if ((GET_CODE (cmp0) == CONST_INT) && (INTVAL (cmp0) != 0)) cmp0 = force_reg (mode, cmp0); /* If the comparison is against an int not in legal range move it into a register. */ if (GET_CODE (cmp1) == CONST_INT) { switch (code) { case EQ: case NE: case LE: case LT: case GE: case GT: if (!satisfies_constraint_K (cmp1)) cmp1 = force_reg (mode, cmp1); break; case LEU: case LTU: case GEU: case GTU: if (!satisfies_constraint_L (cmp1)) cmp1 = force_reg (mode, cmp1); break; default: gcc_unreachable (); } } /* Generate compare instruction. */ emit_move_insn (result, gen_rtx_fmt_ee (code, mode, cmp0, cmp1)); } }
void gen_int_relational (enum rtx_code code, /* relational test (EQ, etc) */ rtx result, /* result to store comp. or 0 if branch */ rtx cmp0, /* first operand to compare */ rtx cmp1, /* second operand to compare */ rtx destination) /* destination of the branch, or 0 if compare */ { enum machine_mode mode; int branch_p; mode = GET_MODE (cmp0); if (mode == VOIDmode) mode = GET_MODE (cmp1); /* Is this a branch or compare */ branch_p = (destination != 0); /* Instruction set doesn't support LE or LT, so swap operands and use GE, GT */ switch (code) { case LE: case LT: case LEU: case LTU: code = swap_condition (code); rtx temp = cmp0; cmp0 = cmp1; cmp1 = temp; break; default: break; } if (branch_p) { rtx insn; /* Operands must be in registers */ if (!register_operand (cmp0, mode)) cmp0 = force_reg (mode, cmp0); if (!register_operand (cmp1, mode)) cmp1 = force_reg (mode, cmp1); /* Generate conditional branch instruction */ rtx cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1); rtx label = gen_rtx_LABEL_REF (VOIDmode, destination); insn = gen_rtx_SET (VOIDmode, pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx)); emit_jump_insn (insn); } else { /* We can't have const_ints in cmp0, other than 0 */ if ((GET_CODE (cmp0) == CONST_INT) && (INTVAL (cmp0) != 0)) cmp0 = force_reg (mode, cmp0); /* If the comparison is against an int not in legal range move it into a register */ if (GET_CODE (cmp1) == CONST_INT) { HOST_WIDE_INT value = INTVAL (cmp1); switch (code) { case EQ: case NE: case LE: case LT: case GE: case GT: if (!MEDIUM_INT(value)) cmp1 = force_reg (mode, cmp1); break; case LEU: case LTU: case GEU: case GTU: if (!MEDIUM_UINT(value)) cmp1 = force_reg (mode, cmp1); break; default: abort (); } } /* Generate compare instruction */ emit_move_insn (result, gen_rtx_fmt_ee (code, mode, cmp0, cmp1)); } }