Example #1
0
/**
 * "continue" statement
 */
void docont(void) {
        WHILE *ptr; //int     *ptr;

        if ((ptr = findwhile ()) == 0)
                return;
        gen_modify_stack (ptr->stack_pointer);
        if (ptr->type == WSFOR)
                gen_jump (ptr->incr_def);
        else
                gen_jump (ptr->case_test);
}
Example #2
0
/**
 * "continue" statement
 */
docont() {
        loop_t *ptr;

        if ((ptr = findloop ()) == 0)
                return;
        gen_modify_stack (ptr->stack_pointer);
        if (ptr->type == WSFOR)
                gen_jump (ptr->cont_label);
        else
                gen_jump (ptr->test_label);
}
Example #3
0
/**
 * "switch" statement
 */
void doswitch(void) {
        WHILE ws;
        WHILE *ptr;

        ws.symbol_idx = local_table_index;
        ws.stack_pointer = stkp;
        ws.type = WSSWITCH;
        ws.case_test = swstp;
        ws.body_tab = getlabel ();
        ws.incr_def = ws.while_exit = getlabel ();
        addwhile (&ws);
        gen_immediate ();
        print_label (ws.body_tab);
        newline ();
        gen_push (HL_REG);
        needbrack ("(");
        expression (YES);
        needbrack (")");
        stkp = stkp + INTSIZE;  // '?case' will adjust the stack
        gen_jump_case ();
        statement (NO);
        ptr = readswitch ();
        gen_jump (ptr->while_exit);
        dumpsw (ptr);
        generate_label (ptr->while_exit);
        local_table_index = ptr->symbol_idx;
        stkp = gen_modify_stack (ptr->stack_pointer);
        swstp = ptr->case_test;
        delwhile ();
}
Example #4
0
/**
 * "switch" statement
 */
doswitch() {
        loop_t loop;
        loop_t *ptr;

        loop.symbol_idx = local_table_index;
        loop.stack_pointer = stkp;
        loop.type = WSSWITCH;
        loop.test_label = swstp;
        loop.body_label = getlabel ();
        loop.cont_label = loop.exit_label = getlabel ();
        addloop (&loop);
        gen_immediate_a ();
        print_label (loop.body_label);
        newline ();
        gen_push ();
        needbrack ("(");
        expression (YES);
        needbrack (")");
        stkp = stkp + INTSIZE;  // '?case' will adjust the stack
        gen_jump_case ();
        statement (NO);
        ptr = readswitch ();
        gen_jump (ptr->exit_label);
        dumpsw (ptr);
        generate_label (ptr->exit_label);
        local_table_index = ptr->symbol_idx;
        stkp = gen_modify_stack (ptr->stack_pointer);
        swstp = ptr->test_label;
        delloop ();
}
Example #5
0
static void
compute_init_costs (void)
{
  rtx rtx_jump, rtx_store, rtx_return, reg, label;
  basic_block bb;

  FOR_EACH_BB (bb)
    if (BB_HEAD (bb))
      break;

  label = block_label (bb);
  reg = gen_rtx_REG (Pmode, 0);

  /* Pattern for indirect jump.  */
  rtx_jump = gen_indirect_jump (reg);

  /* Pattern for storing address.  */
  rtx_store = gen_rtx_SET (VOIDmode, reg, gen_symbol_ref_rtx_for_label (label));

  /* Pattern for return insn.  */
  rtx_return = gen_jump (label);

  /* The cost of jump.  */
  seq_jump_cost = compute_rtx_cost (make_jump_insn_raw (rtx_jump));

  /* The cost of calling sequence.  */
  seq_call_cost = seq_jump_cost + compute_rtx_cost (make_insn_raw (rtx_store));

  /* The cost of return.  */
  seq_return_cost = compute_rtx_cost (make_jump_insn_raw (rtx_return));

  /* Simple heuristic for minimal sequence cost.  */
  seq_call_cost   = (int)(seq_call_cost * (double)SEQ_CALL_COST_MULTIPLIER);
}
Example #6
0
/**
 * "break" statement
 */
void dobreak(void) {
        WHILE *ptr;

        if ((ptr = readwhile ()) == 0)
                return;
        gen_modify_stack (ptr->stack_pointer);
        gen_jump (ptr->while_exit);
}
Example #7
0
/**
 * "break" statement
 */
dobreak() {
        loop_t *ptr;

        if ((ptr = readloop ()) == 0)
                return;
        gen_modify_stack (ptr->stack_pointer);
        gen_jump (ptr->exit_label);
}
Example #8
0
static void
erase_matching_seqs (void)
{
  seq_block sb;
  matching_seq mseq;
  rtx insn;
  basic_block bb;
  rtx retlabel, saveinsn, callinsn;
  int i;

  for (sb = seq_blocks; sb; sb = sb->next_seq_block)
    {
      for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
        {
          insn = mseq->insn;
          bb = BLOCK_FOR_INSN (insn);

          /* Get the label after the sequence. This will be the return
             address. The label will be referenced using a symbol_ref so
             protect it from deleting.  */
          retlabel = block_label_after (insn);
          LABEL_PRESERVE_P (retlabel) = 1;

          /* Delete the insns of the sequence.  */
          for (i = 0; i < sb->length; i++)
            insn = prev_insn_in_block (insn);
          delete_basic_block (split_block_and_df_analyze (bb, insn));

          /* Emit an insn saving the return address to the link register
             before the deleted sequence.  */
          saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg,
                                      gen_symbol_ref_rtx_for_label
                                      (retlabel)),
                                      BB_END (bb));
          BLOCK_FOR_INSN (saveinsn) = bb;

          /* Emit a jump to the appropriate part of the pattern sequence
             after the save insn. Also update the basic block.  */
          callinsn = emit_jump_insn_after (gen_jump (sb->label), saveinsn);
          JUMP_LABEL (callinsn) = sb->label;
          LABEL_NUSES (sb->label)++;
          BLOCK_FOR_INSN (callinsn) = bb;
          BB_END (bb) = callinsn;

          /* Maintain control flow and liveness information.  */
          SET_REGNO_REG_SET (df_get_live_out (bb),
                             REGNO (pattern_seqs->link_reg));
          emit_barrier_after (BB_END (bb));
          make_single_succ_edge (bb, BLOCK_FOR_INSN (sb->label), 0);
          IOR_REG_SET (df_get_live_out (bb),
		       df_get_live_in (BLOCK_FOR_INSN (sb->label)));

          make_edge (BLOCK_FOR_INSN (seq_blocks->label),
                     BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);
        }
    }
}
Example #9
0
/* Delayed conditional jump (bt or bf) */
static void gen_delayed_conditional_jump(DisasContext * ctx)
{
    int l1;

    l1 = gen_new_label();
    gen_op_jdelayed(l1);
    gen_goto_tb(ctx, 1, ctx->pc);
    gen_set_label(l1);
    gen_jump(ctx);
}
Example #10
0
/**
 * "for" statement
 */
dofor() {
        loop_t loop;
        loop_t *p;

        loop.symbol_idx = local_table_index;
        loop.stack_pointer = stkp;
        loop.type = WSFOR;
        loop.test_label = getlabel ();
        loop.cont_label = getlabel ();
        loop.body_label = getlabel ();
        loop.exit_label = getlabel ();
        addloop (&loop);
        p = readloop ();
        needbrack ("(");
        if (!match (";")) {
                expression (YES);
                need_semicolon ();
        }
        generate_label (p->test_label);
        if (!match (";")) {
                expression (YES);
                gen_test_jump (p->body_label, TRUE);
                gen_jump (p->exit_label);
                need_semicolon ();
        } else
                p->test_label = p->body_label;
        generate_label (p->cont_label);
        if (!match (")")) {
                expression (YES);
                needbrack (")");
                gen_jump (p->test_label);
        } else
                p->cont_label = p->test_label;
        generate_label (p->body_label);
        statement (NO);
        gen_jump (p->cont_label);
        generate_label (p->exit_label);
        local_table_index = p->symbol_idx;
        stkp = gen_modify_stack (p->stack_pointer);
        delloop ();
}
Example #11
0
/**
 * "for" statement
 */
void dofor(void) {
        WHILE ws;
        WHILE *pws;

        ws.symbol_idx = local_table_index;
        ws.stack_pointer = stkp;
        ws.type = WSFOR;
        ws.case_test = getlabel ();
        ws.incr_def = getlabel ();
        ws.body_tab = getlabel ();
        ws.while_exit = getlabel ();
        addwhile (&ws);
        pws = readwhile ();
        needbrack ("(");
        if (!match (";")) {
                expression (YES);
                need_semicolon ();
        }
        generate_label (pws->case_test);
        if (!match (";")) {
                expression (YES);
                gen_test_jump (pws->body_tab, TRUE);
                gen_jump (pws->while_exit);
                need_semicolon ();
        } else
                pws->case_test = pws->body_tab;
        generate_label (pws->incr_def);
        if (!match (")")) {
                expression (YES);
                needbrack (")");
                gen_jump (pws->case_test);
        } else
                pws->incr_def = pws->case_test;
        generate_label (pws->body_tab);
        statement (NO);
        gen_jump (pws->incr_def);
        generate_label (pws->while_exit);
        local_table_index = pws->symbol_idx;
        stkp = gen_modify_stack (pws->stack_pointer);
        delwhile ();
}
Example #12
0
/* Generate code for transformation 2 (with MODE and OPERATION, operands OP1
   and OP2, result TARGET and probability of taking the optimal path PROB).  */
static rtx
gen_mod_pow2 (enum machine_mode mode, enum rtx_code operation, rtx target,
	      rtx op1, rtx op2, int prob)
{
  rtx tmp, tmp1, tmp2, tmp3, jump;
  rtx neq_label = gen_label_rtx ();
  rtx end_label = gen_label_rtx ();
  rtx sequence;

  start_sequence ();
  
  if (!REG_P (op2))
    {
      tmp = gen_reg_rtx (mode);
      emit_move_insn (tmp, copy_rtx (op2));
    }
  else
    tmp = op2;

  tmp1 = expand_simple_binop (mode, PLUS, tmp, constm1_rtx, NULL_RTX,
			      0, OPTAB_WIDEN);
  tmp2 = expand_simple_binop (mode, AND, tmp, tmp1, NULL_RTX,
			      0, OPTAB_WIDEN);
  do_compare_rtx_and_jump (tmp2, const0_rtx, NE, 0, mode, NULL_RTX,
			   NULL_RTX, neq_label);

  /* Add branch probability to jump we just created.  */
  jump = get_last_insn ();
  REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB,
					GEN_INT (REG_BR_PROB_BASE - prob),
					REG_NOTES (jump));

  tmp3 = expand_simple_binop (mode, AND, op1, tmp1, target,
			      0, OPTAB_WIDEN);
  if (tmp3 != target)
    emit_move_insn (copy_rtx (target), tmp3);
  emit_jump_insn (gen_jump (end_label));
  emit_barrier ();

  emit_label (neq_label);
  tmp1 = simplify_gen_binary (operation, mode, copy_rtx (op1), copy_rtx (tmp));
  tmp1 = force_operand (tmp1, target);
  if (tmp1 != target)
    emit_move_insn (target, tmp1);
  
  emit_label (end_label);

  sequence = get_insns ();
  end_sequence ();
  rebuild_jump_labels (sequence);
  return sequence;
}
Example #13
0
/* Generate code for transformation 1 (with MODE and OPERATION, operands OP1
   and OP2, whose value is expected to be VALUE, result TARGET and
   probability of taking the optimal path PROB).  */
static rtx
gen_divmod_fixed_value (enum machine_mode mode, enum rtx_code operation,
			rtx target, rtx op1, rtx op2, gcov_type value,
			int prob)
{
  rtx tmp, tmp1, jump;
  rtx neq_label = gen_label_rtx ();
  rtx end_label = gen_label_rtx ();
  rtx sequence;

  start_sequence ();
  
  if (!REG_P (op2))
    {
      tmp = gen_reg_rtx (mode);
      emit_move_insn (tmp, copy_rtx (op2));
    }
  else
    tmp = op2;

  do_compare_rtx_and_jump (tmp, GEN_INT (value), NE, 0, mode, NULL_RTX,
			   NULL_RTX, neq_label);

  /* Add branch probability to jump we just created.  */
  jump = get_last_insn ();
  REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB,
					GEN_INT (REG_BR_PROB_BASE - prob),
					REG_NOTES (jump));

  tmp1 = simplify_gen_binary (operation, mode,
			      copy_rtx (op1), GEN_INT (value));
  tmp1 = force_operand (tmp1, target);
  if (tmp1 != target)
    emit_move_insn (copy_rtx (target), copy_rtx (tmp1));

  emit_jump_insn (gen_jump (end_label));
  emit_barrier ();

  emit_label (neq_label);
  tmp1 = simplify_gen_binary (operation, mode,
			      copy_rtx (op1), copy_rtx (tmp));
  tmp1 = force_operand (tmp1, target);
  if (tmp1 != target)
    emit_move_insn (copy_rtx (target), copy_rtx (tmp1));
  
  emit_label (end_label);

  sequence = get_insns ();
  end_sequence ();
  rebuild_jump_labels (sequence);
  return sequence;
}
Example #14
0
static int
get_uncond_jump_length (void)
{
  rtx label, jump;
  int length;

  label = emit_label_before (gen_label_rtx (), get_insns ());
  jump = emit_jump_insn (gen_jump (label));

  length = get_attr_length (jump);

  delete_insn (jump);
  delete_insn (label);
  return length;
}
Example #15
0
/**
 * "while" statement
 */
dowhile() {
        loop_t loop;

        loop.symbol_idx = local_table_index;
        loop.stack_pointer = stkp;
        loop.type = WSWHILE;
        loop.test_label = getlabel ();
        loop.exit_label = getlabel ();
        addloop (&loop);
        generate_label (loop.test_label);
        test (loop.exit_label, FALSE);
        statement (NO);
        gen_jump (loop.test_label);
        generate_label (loop.exit_label);
        local_table_index = loop.symbol_idx;
        stkp = gen_modify_stack (loop.stack_pointer);
        delloop ();
}
Example #16
0
/**
 * "while" statement
 */
void dowhile(void) {
        WHILE ws;

        ws.symbol_idx = local_table_index;
        ws.stack_pointer = stkp;
        ws.type = WSWHILE;
        ws.case_test = getlabel ();
        ws.while_exit = getlabel ();
        addwhile (&ws);
        generate_label (ws.case_test);
        test (ws.while_exit, FALSE);
        statement (NO);
        gen_jump (ws.case_test);
        generate_label (ws.while_exit);
        local_table_index = ws.symbol_idx;
        stkp = gen_modify_stack (ws.stack_pointer);
        delwhile ();
}
Example #17
0
void append_c_instruction(output_file* file, c_inst inst)
{
	// 1 1 1 a c1 c2 c3 c4 c5 c6 d1 d2 d3 j1 j2 j3

	char binary[16];

	// C instructions has 3 leading 1's
	binary[15] = '1';
	binary[14] = '1';
	binary[13] = '1';

	for (int i = 15; i >= 0; i--)
	{
		binary[i] = '1';
	}

	gen_dest(binary, inst.dest);
	gen_comp(binary, inst.comp);
	gen_jump(binary, inst.jump);

	write(binary, file);
}
Example #18
0
/**
 * "if" statement
 */
void doif(void) {
        int     fstkp, flab1, flab2;
        int     flev;

        flev = local_table_index;
        fstkp = stkp;
        flab1 = getlabel ();
        test (flab1, FALSE);
        statement (NO);
        stkp = gen_modify_stack (fstkp);
        local_table_index = flev;
        if (!amatch ("else", 4)) {
                generate_label (flab1);
                return;
        }
        gen_jump (flab2 = getlabel ());
        generate_label (flab1);
        statement (NO);
        stkp = gen_modify_stack (fstkp);
        local_table_index = flev;
        generate_label (flab2);
}
Example #19
0
/**
 * "return" statement
 */
void doreturn(void) {
        if (endst () == 0)
                expression (YES);
        gen_jump(fexitlab);
}