/** * "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); }
/** * "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); }
/** * "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 (); }
/** * "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 (); }
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); }
/** * "break" statement */ void dobreak(void) { WHILE *ptr; if ((ptr = readwhile ()) == 0) return; gen_modify_stack (ptr->stack_pointer); gen_jump (ptr->while_exit); }
/** * "break" statement */ dobreak() { loop_t *ptr; if ((ptr = readloop ()) == 0) return; gen_modify_stack (ptr->stack_pointer); gen_jump (ptr->exit_label); }
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); } } }
/* 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); }
/** * "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 (); }
/** * "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 (); }
/* 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; }
/* 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; }
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; }
/** * "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 (); }
/** * "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 (); }
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); }
/** * "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); }
/** * "return" statement */ void doreturn(void) { if (endst () == 0) expression (YES); gen_jump(fexitlab); }