void emit_format(){ emit_label(".DEC");//emit format of integer. emit_ascii("%d\\n"); //fprintf(fp," .ascii \"%%d\\n\\0\"\n"); emit_label(".HEX"); emit_ascii("0x%X\\n"); //fprintf(fp," .ascii \"%%X\\n\\0\"\n"); }
void emitstmt(void* stmt){ Syntax *st = (Syntax*) stmt; if(st->type == IF_STATEMENT){ int label = labelconditionid++; char c[10]; emit_condition(st->if_statement->condition,label); emitblock(st->if_statement->then); sprintf(c,".LC%d",label); emit_label(c); }else if(st->type == WHILE_SYNTAX){ int labelcondition,labelblock; labelcondition = labelconditionid++; labelblock = labelconditionid++; char c[10]; emit_instr_format("jmp",".LC%d",labelcondition);//to check condition sprintf(c,".LC%d",labelblock); emit_label(c); emitblock(st->while_statement->body); sprintf(c,".LC%d",labelcondition); emit_label(c); emit_condition(st->while_statement->condition,labelblock); }else if(st->type == PRINT_STATEMENT){ emit_instr_format("leaq","%s(%%rip), %%rcx",st->printstmt->tag); emit_ins("call","printf"); }else if(st->type == PRINTDEC_STATEMENT){ emit_expression(st->printexp->exp); emit_ins("movq","%%rax, %%rdx"); emit_ins("leaq",".DEC(%%rip), %%rcx");//.DEC print dec format emit_ins("call","printf"); }else if(st->type == PRINTHEX_STATEMENT){ emit_expression(st->printexp->exp); emit_ins("movq","%%rax, %%rdx"); emit_ins("leaq",".HEX(%%rip), %%rcx");//.HEX print hex format emit_ins("call","printf"); }else if(st->type == ASSIGNMENT){ int tempoffset = findOffsetVar(st->assignment->var_name);//not found is -1 if(tempoffset == -1){ OffsetVarmap* temp = (OffsetVarmap*)malloc(sizeof(OffsetVarmap)); temp->varname = st->assignment->var_name; temp->offset = offset; tempoffset = offset; //printf("offset %d \n",offset); offset = offset+8; list_push(tablevar,temp); } emit_expression(st->assignment->expression); emit_instr_format("movq","%%rax, -%d(%%rbp)",tempoffset);//result to variable. }else if(st->type == VARIABLE){ OffsetVarmap *temp = (OffsetVarmap*)malloc(sizeof(OffsetVarmap)); temp->varname = st->variable->var_name; temp->offset = offset; offset = offset+8; list_push(tablevar,temp); }else{ fprintf(fp,"statement error"); } }
static void emit_literal(Node *node) { SAVE; switch (node->ty->kind) { case KIND_BOOL: case KIND_CHAR: case KIND_SHORT: emit("mov $%u, #rax", node->ival); break; case KIND_INT: emit("mov $%u, #rax", node->ival); break; case KIND_LONG: case KIND_LLONG: { emit("mov $%lu, #rax", node->ival); break; } case KIND_FLOAT: { if (!node->flabel) { node->flabel = make_label(); float fval = node->fval; emit_noindent(".data"); emit_label(node->flabel); emit(".long %d", *(uint32_t *)&fval); emit_noindent(".text"); } emit("movss %s(#rip), #xmm0", node->flabel); break; } case KIND_DOUBLE: case KIND_LDOUBLE: { if (!node->flabel) { node->flabel = make_label(); emit_noindent(".data"); emit_label(node->flabel); emit(".quad %lu", *(uint64_t *)&node->fval); emit_noindent(".text"); } emit("movsd %s(#rip), #xmm0", node->flabel); break; } case KIND_ARRAY: { if (!node->slabel) { node->slabel = make_label(); emit_noindent(".data"); emit_label(node->slabel); emit(".string \"%s\"", quote_cstring_len(node->sval, node->ty->size)); emit_noindent(".text"); } emit("lea %s(#rip), #rax", node->slabel); break; } default: error("internal error"); } }
/* 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 while_stmt(stream, node, brk, cont, ret) { cont = new_label(); emit_label( stream, cont ); expr_code( stream, node[3], 0 ); brk = new_label(); branch_ifz( stream, brk ); stmt_code( stream, node[4], brk, cont, ret ); branch( stream, cont ); emit_label( stream, brk ); }
static void emit_do(Node *node) { SAVE; char *begin = make_label(); char *end = make_label(); SET_JUMP_LABELS(end, begin); emit_label(begin); if (node->forbody) emit_expr(node->forbody); emit_expr(node->forcond); emit_je(end); emit_jmp(begin); emit_label(end); RESTORE_JUMP_LABELS(); }
static void emit_switch(Node *node) { SAVE; char *oswitch = lswitch, *obreak = lbreak; emit_expr(node->switchexpr); lswitch = make_label(); lbreak = make_label(); emit_jmp(lswitch); if (node->switchbody) emit_expr(node->switchbody); emit_label(lswitch); emit_label(lbreak); lswitch = oswitch; lbreak = obreak; }
static conditional(stream, node) { auto l1 = new_label(), l2 = new_label(); expr_code( stream, node[3], 0 ); branch_ifz( stream, l1 ); expr_code( stream, node[4], 0 ); branch( stream, l2 ); emit_label( stream, l1 ); expr_code( stream, node[5], 0 ); emit_label( stream, l2 ); }
static do_stmt(stream, node, brk, cont, ret) { auto start = new_label(); emit_label( stream, start ); cont = new_label(); brk = new_label(); stmt_code( stream, node[3], brk, cont, ret ); emit_label( stream, cont ); expr_code( stream, node[4], 0 ); branch_ifnz( stream, start ); emit_label( stream, brk ); }
static switch_stmt(stream, node, brk, cont, ret) { auto i = 0, def; expr_code( stream, node[3], 0 ); def = brk = new_label(); if (node[5][0] != 'swtb') int_error("No table for switch statement"); while ( i < node[5][1] ) { auto c = node[5][3 + i++]; /* Make asm labels for each case label. We store these as integers * in the unused 3rd operator slot of the case node. */ c[5] = new_label(); if (c[0] == 'case') /* Case labels have to be integers */ branch_eq_n( stream, c[3][3], c[5] ); else def = c[5]; } branch( stream, def ); stmt_code( stream, node[4], brk, cont, ret ); emit_label( stream, brk ); }
static case_stmt(stream, node, brk, cont, ret) { /* The case labels were written into the unused 3rd operator slot of * the case node by switch_stmt(), below. */ emit_label( stream, node[5] ); stmt_code( stream, node[4], brk, cont, ret ); }
static void do_jump_by_parts_equality_rtx (enum machine_mode mode, rtx op0, rtx op1, rtx if_false_label, rtx if_true_label, int prob) { int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); rtx drop_through_label = 0; int i; if (op1 == const0_rtx) { do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label, prob); return; } else if (op0 == const0_rtx) { do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label, prob); return; } if (! if_false_label) drop_through_label = if_false_label = gen_label_rtx (); for (i = 0; i < nwords; i++) do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), operand_subword_force (op1, i, mode), EQ, 0, word_mode, NULL_RTX, if_false_label, NULL_RTX, prob); if (if_true_label) emit_jump (if_true_label); if (drop_through_label) emit_label (drop_through_label); }
static void emit_default(Node *node) { SAVE; if (!lswitch) error("stray case label"); emit_label(lswitch); lswitch = make_label(); }
void emit_str(Stack* string_stack){ while(!stack_empty(string_stack)){ Syntax *syntax = (Syntax*)stack_pop(string_stack); emit_label(syntax->printstmt->tag); emit_ascii(syntax->printstmt->value); } }
void while_loop () { int loop_to = emit_label(new_label()); int break_to = new_label(); bool do_while = try_match("do"); if (do_while) line(); match("while"); match("("); expr(0); match(")"); fprintf(output, "cmp eax, 0\n" "je _%08d\n", break_to); if (do_while) match(";"); else line(); fprintf(output, "jmp _%08d\n", loop_to); fprintf(output, "\t_%08d:\n", break_to); }
inline void If::gen(const std::uint32_t &b, const std::uint32_t &a) { auto label = new_label(); expr_->jumping(0, a); emit_label(label); statement_->gen(label, a); }
static bool nds32_expand_setmem_loop_v3m (rtx dstmem, rtx size, rtx value) { rtx base_reg = copy_to_mode_reg (Pmode, XEXP (dstmem, 0)); rtx need_align_bytes = gen_reg_rtx (SImode); rtx last_2_bit = gen_reg_rtx (SImode); rtx byte_loop_base = gen_reg_rtx (SImode); rtx byte_loop_size = gen_reg_rtx (SImode); rtx remain_size = gen_reg_rtx (SImode); rtx new_base_reg; rtx value4byte, value4doubleword; rtx byte_mode_size; rtx last_byte_loop_label = gen_label_rtx (); size = force_reg (SImode, size); value4doubleword = nds32_gen_dup_8_byte_to_double_word_value (value); value4byte = simplify_gen_subreg (QImode, value4doubleword, DImode, subreg_lowpart_offset (QImode, DImode)); emit_move_insn (byte_loop_size, size); emit_move_insn (byte_loop_base, base_reg); /* Jump to last byte loop if size is less than 16. */ emit_cmp_and_jump_insns (size, gen_int_mode (16, SImode), LE, NULL, SImode, 1, last_byte_loop_label); /* Make sure align to 4 byte first since v3m can't unalign access. */ emit_insn (gen_andsi3 (last_2_bit, base_reg, gen_int_mode (0x3, SImode))); emit_insn (gen_subsi3 (need_align_bytes, gen_int_mode (4, SImode), last_2_bit)); /* Align to 4 byte. */ new_base_reg = emit_setmem_byte_loop (base_reg, need_align_bytes, value4byte, true); /* Calculate remain size. */ emit_insn (gen_subsi3 (remain_size, size, need_align_bytes)); /* Set memory word by word. */ byte_mode_size = emit_setmem_doubleword_loop (new_base_reg, remain_size, value4doubleword); emit_move_insn (byte_loop_base, new_base_reg); emit_move_insn (byte_loop_size, byte_mode_size); emit_label (last_byte_loop_label); /* And set memory for remain bytes. */ emit_setmem_byte_loop (byte_loop_base, byte_loop_size, value4byte, false); return true; }
static void emit_expr(Node *node) { SAVE; switch (node->type) { case AST_LITERAL: emit_literal(node); return; case AST_STRING: emit_literal_string(node); return; case AST_LVAR: emit_lvar(node); return; case AST_GVAR: emit_gvar(node); return; case AST_FUNCALL: case AST_FUNCPTR_CALL: emit_func_call(node); return; case AST_DECL: emit_decl(node); return; case AST_CONV: emit_conv(node); return; case AST_ADDR: emit_addr(node->operand); return; case AST_DEREF: emit_deref(node); return; case AST_IF: case AST_TERNARY: emit_ternary(node); return; case AST_FOR: emit_for(node); return; case AST_WHILE: emit_while(node); return; case AST_DO: emit_do(node); return; case AST_SWITCH: emit_switch(node); return; case AST_CASE: emit_case(node); return; case AST_DEFAULT: emit_default(node); return; case AST_GOTO: emit_goto(node); return; case AST_LABEL: if (node->newlabel) emit_label(node->newlabel); return; case AST_RETURN: emit_return(node); return; case AST_BREAK: emit_break(node); return; case AST_CONTINUE: emit_continue(node); return; case AST_COMPOUND_STMT: emit_compound_stmt(node); return; case AST_STRUCT_REF: emit_load_struct_ref(node->struc, node->ctype, 0); return; case AST_VA_START: emit_va_start(node); return; case AST_VA_ARG: emit_va_arg(node); return; case OP_UMINUS: emit_uminus(node); return; case OP_PRE_INC: emit_pre_inc_dec(node, "add"); return; case OP_PRE_DEC: emit_pre_inc_dec(node, "sub"); return; case OP_POST_INC: emit_post_inc_dec(node, "add"); return; case OP_POST_DEC: emit_post_inc_dec(node, "sub"); return; case '!': emit_lognot(node); return; case '&': emit_bitand(node); return; case '|': emit_bitor(node); return; case '~': emit_bitnot(node); return; case OP_LOGAND: emit_logand(node); return; case OP_LOGOR: emit_logor(node); return; case OP_CAST: emit_cast(node); return; case ',': emit_comma(node); return; case '=': emit_assign(node); return; case OP_LABEL_ADDR: emit_label_addr(node); return; case AST_COMPUTED_GOTO: emit_computed_goto(node); return; default: emit_binop(node); } }
static void emit_builtin_return_address(Node *node) { push("r11"); assert(vec_len(node->args) == 1); emit_expr(vec_head(node->args)); char *loop = make_label(); char *end = make_label(); emit("mov #rbp, #r11"); emit_label(loop); emit("test #rax, #rax"); emit("jz %s", end); emit("mov (#r11), #r11"); emit("sub $1, #rax"); emit_jmp(loop); emit_label(end); emit("mov 8(#r11), #rax"); pop("r11"); }
static void unroll_op(pTHX_ struct sljit_compiler* compiler, OP* op) { DEBUGf((" ; %s [%p]\n", OP_NAME(op), op)); emit_label(compiler, op); // TODO(dgl): Can we avoid doing this for every op? sljit_emit_ijump(compiler, SLJIT_CALL0, SLJIT_IMM, (sljit_w) op->op_ppaddr); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM, (sljit_w) &PL_op, SLJIT_RETURN_REG, 0); }
static void emit_ternary(Node *node) { SAVE; emit_expr(node->cond); char *ne = make_label(); emit_je(ne); if (node->then) emit_expr(node->then); if (node->els) { char *end = make_label(); emit_jmp(end); emit_label(ne); emit_expr(node->els); emit_label(end); } else { emit_label(ne); } }
static void emit_literal(Node *node) { SAVE; switch (node->ctype->type) { case CTYPE_BOOL: case CTYPE_CHAR: emit("mov $%d, %%rax", node->ival); break; case CTYPE_INT: emit("mov $%d, %%rax", node->ival); break; case CTYPE_LONG: case CTYPE_LLONG: { emit("mov $%lu, %%rax", node->ival); break; } case CTYPE_FLOAT: { if (!node->flabel) { node->flabel = make_label(); float fval = node->fval; int *p = (int *)&fval; emit_noindent(".data"); emit_label(node->flabel); emit(".long %d", *p); emit_noindent(".text"); } emit("movss %s(%%rip), %%xmm0", node->flabel); break; } case CTYPE_DOUBLE: case CTYPE_LDOUBLE: { if (!node->flabel) { node->flabel = make_label(); int *fval = (int *)&node->fval; emit_noindent(".data"); emit_label(node->flabel); emit(".long %d", fval[0]); emit(".long %d", fval[1]); emit_noindent(".text"); } emit("movsd %s(%%rip), %%xmm0", node->flabel); break; } default: error("internal error"); } }
static void emit_data_charptr(char *s, int depth) { char *label = make_label(); emit(".data %d", depth + 1); emit_label(label); emit(".string \"%s\"", quote_cstring(s)); emit(".data %d", depth); emit(".quad %s", label); }
bool nds32_expand_strlen (rtx result, rtx str, rtx target_char, rtx align ATTRIBUTE_UNUSED) { rtx base_reg, backup_base_reg; rtx ffb_result; rtx target_char_ptr, length; rtx loop_label, tmp; if (optimize_size || optimize < 3) return false; gcc_assert (MEM_P (str)); gcc_assert (CONST_INT_P (target_char) || REG_P (target_char)); base_reg = copy_to_mode_reg (SImode, XEXP (str, 0)); loop_label = gen_label_rtx (); ffb_result = gen_reg_rtx (Pmode); tmp = gen_reg_rtx (SImode); backup_base_reg = gen_reg_rtx (SImode); /* Emit loop version of strlen. move $backup_base, $base .Lloop: lmw.bim $tmp, [$base], $tmp, 0 ffb $ffb_result, $tmp, $target_char ! is there $target_char? beqz $ffb_result, .Lloop add $last_char_ptr, $base, $ffb_result sub $length, $last_char_ptr, $backup_base */ /* move $backup_base, $base */ emit_move_insn (backup_base_reg, base_reg); /* .Lloop: */ emit_label (loop_label); /* lmw.bim $tmp, [$base], $tmp, 0 */ emit_insn (gen_unaligned_load_update_base_w (base_reg, tmp, base_reg)); /* ffb $ffb_result, $tmp, $target_char ! is there $target_char? */ emit_insn (gen_unspec_ffb (ffb_result, tmp, target_char)); /* beqz $ffb_result, .Lloop */ emit_cmp_and_jump_insns (ffb_result, const0_rtx, EQ, NULL, SImode, 1, loop_label); /* add $target_char_ptr, $base, $ffb_result */ target_char_ptr = expand_binop (Pmode, add_optab, base_reg, ffb_result, NULL_RTX, 0, OPTAB_WIDEN); /* sub $length, $target_char_ptr, $backup_base */ length = expand_binop (Pmode, sub_optab, target_char_ptr, backup_base_reg, NULL_RTX, 0, OPTAB_WIDEN); emit_move_insn (result, length); return true; }
static rtx emit_setmem_doubleword_loop (rtx itr, rtx size, rtx value) { rtx word_mode_label = gen_label_rtx (); rtx word_mode_end_label = gen_label_rtx (); rtx byte_mode_size = gen_reg_rtx (SImode); rtx byte_mode_size_tmp = gen_reg_rtx (SImode); rtx word_mode_end = gen_reg_rtx (SImode); rtx size_for_word = gen_reg_rtx (SImode); /* and $size_for_word, $size, #~0x7 */ size_for_word = expand_binop (SImode, and_optab, size, gen_int_mode (~0x7, SImode), NULL_RTX, 0, OPTAB_WIDEN); emit_move_insn (byte_mode_size, size); /* beqz $size_for_word, .Lbyte_mode_entry */ emit_cmp_and_jump_insns (size_for_word, const0_rtx, EQ, NULL, SImode, 1, word_mode_end_label); /* add $word_mode_end, $dst, $size_for_word */ word_mode_end = expand_binop (Pmode, add_optab, itr, size_for_word, NULL_RTX, 0, OPTAB_WIDEN); /* andi $byte_mode_size, $size, 0x7 */ byte_mode_size_tmp = expand_binop (SImode, and_optab, size, GEN_INT (0x7), NULL_RTX, 0, OPTAB_WIDEN); emit_move_insn (byte_mode_size, byte_mode_size_tmp); /* .Lword_mode: */ emit_label (word_mode_label); /* ! word-mode set loop smw.bim $value4word, [$dst_itr], $value4word, 0 bne $word_mode_end, $dst_itr, .Lword_mode */ emit_insn (gen_unaligned_store_update_base_dw (itr, itr, value)); emit_cmp_and_jump_insns (word_mode_end, itr, NE, NULL, Pmode, 1, word_mode_label); emit_label (word_mode_end_label); return byte_mode_size; }
static void emit_case(Node *node) { SAVE; if (!lswitch) error("stray case label"); char *skip = make_label(); emit_jmp(skip); emit_label(lswitch); lswitch = make_label(); emit("cmp $%d, %%eax", node->casebeg); if (node->casebeg == node->caseend) { emit("jne %s", lswitch); } else { emit("jl %s", lswitch); emit("cmp $%d, %%eax", node->caseend); emit("jg %s", lswitch); } emit_label(skip); }
static if_stmt(stream, node, brk, cont, ret) { auto l1 = new_label(), l2 = l1; expr_code( stream, node[3], 0 ); branch_ifz( stream, l1 ); stmt_code( stream, node[4], brk, cont, ret ); if ( node[5] ) { l2 = new_label(); branch( stream, l2 ); emit_label( stream, l1 ); stmt_code( stream, node[5], brk, cont, ret ); } emit_label( stream, l2 ); }
static fn_decl(stream, name, decl, block, frame_sz) { auto ret = new_label(); start_fn(decl); prolog(stream, name, frame_sz); do_block(stream, block, -1, -1, ret); emit_label( stream, ret ); epilog(stream, frame_sz); end_fn(); }
/* Generate code for transformations 3 and 4 (with MODE and OPERATION, operands OP1 and OP2, result TARGET, at most SUB subtractions, and probability of taking the optimal path(s) PROB1 and PROB2). */ static rtx gen_mod_subtract (enum machine_mode mode, enum rtx_code operation, rtx target, rtx op1, rtx op2, int sub, int prob1, int prob2) { rtx tmp, tmp1, jump; rtx end_label = gen_label_rtx (); rtx sequence; int i; start_sequence (); if (!REG_P (op2)) { tmp = gen_reg_rtx (mode); emit_move_insn (tmp, copy_rtx (op2)); } else tmp = op2; emit_move_insn (target, copy_rtx (op1)); do_compare_rtx_and_jump (target, tmp, LTU, 0, mode, NULL_RTX, NULL_RTX, end_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 (prob1), REG_NOTES (jump)); for (i = 0; i < sub; i++) { tmp1 = expand_simple_binop (mode, MINUS, target, tmp, target, 0, OPTAB_WIDEN); if (tmp1 != target) emit_move_insn (target, tmp1); do_compare_rtx_and_jump (target, tmp, LTU, 0, mode, NULL_RTX, NULL_RTX, end_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 (prob2), REG_NOTES (jump)); } tmp1 = simplify_gen_binary (operation, mode, copy_rtx (target), 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; }