@@ -463,6 +463,22 @@ int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constrain
463463 }
464464 flags = IR_USE_SHOULD_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG;
465465 break;
466+ case IR_COND:
467+ insn = &ctx->ir_base[ref];
468+ n = 0;
469+ if (IR_IS_CONST_REF(insn->op1)) {
470+ constraints->tmp_regs[n] = IR_TMP_REG(1, ctx->ir_base[insn->op1].type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
471+ n++;
472+ }
473+ if (IR_IS_CONST_REF(insn->op2)) {
474+ constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
475+ n++;
476+ }
477+ if (IR_IS_CONST_REF(insn->op3)) {
478+ constraints->tmp_regs[n] = IR_TMP_REG(3, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
479+ n++;
480+ }
481+ break;
466482 case IR_COPY_INT:
467483 case IR_COPY_FP:
468484 flags = IR_DEF_REUSES_OP1_REG | IR_USE_MUST_BE_IN_REG;
@@ -2138,6 +2154,18 @@ static void ir_emit_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
21382154 case IR_GT:
21392155 | cset Rw(def_reg), gt
21402156 break;
2157+ case IR_ULT:
2158+ | cset Rw(def_reg), lt
2159+ break;
2160+ case IR_UGE:
2161+ | cset Rw(def_reg), hs
2162+ break;
2163+ case IR_ULE:
2164+ | cset Rw(def_reg), le
2165+ break;
2166+ case IR_UGT:
2167+ | cset Rw(def_reg), hi
2168+ break;
21412169 }
21422170 if (IR_REG_SPILLED(ctx->regs[def][0])) {
21432171 ir_emit_store(ctx, insn->type, def, def_reg);
@@ -2212,7 +2240,11 @@ static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn
22122240 ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
22132241 if (true_block == next_block) {
22142242 /* swap to avoid unconditional JMP */
2215- op ^= 1; // reverse
2243+ if (int_cmp || op == IR_EQ || op == IR_NE) {
2244+ op ^= 1; // reverse
2245+ } else {
2246+ op ^= 5; // reverse
2247+ }
22162248 true_block = false_block;
22172249 false_block = 0;
22182250 } else if (false_block == next_block) {
@@ -2276,6 +2308,18 @@ static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn
22762308 case IR_GT:
22772309 | bgt =>true_block
22782310 break;
2311+ case IR_ULT:
2312+ | blt =>true_block
2313+ break;
2314+ case IR_UGE:
2315+ | bhs =>true_block
2316+ break;
2317+ case IR_ULE:
2318+ | ble =>true_block
2319+ break;
2320+ case IR_UGT:
2321+ | bhi =>true_block
2322+ break;
22792323// case IR_ULT: fprintf(stderr, "\tjb .LL%d\n", true_block); break;
22802324// case IR_UGE: fprintf(stderr, "\tjae .LL%d\n", true_block); break;
22812325// case IR_ULE: fprintf(stderr, "\tjbe .LL%d\n", true_block); break;
@@ -2421,15 +2465,15 @@ static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn)
24212465
24222466 if (IR_IS_TYPE_INT(type)) {
24232467 if (ir_type_size[type] == 8) {
2424- | csel Rx(def_reg), Rx(op2_reg), Rx(op3_reg), eq
2468+ | csel Rx(def_reg), Rx(op2_reg), Rx(op3_reg), ne
24252469 } else {
2426- | csel Rw(def_reg), Rw(op2_reg), Rw(op3_reg), eq
2470+ | csel Rw(def_reg), Rw(op2_reg), Rw(op3_reg), ne
24272471 }
24282472 } else{
24292473 if (type == IR_DOUBLE) {
2430- | fcsel Rd(def_reg-IR_REG_FP_FIRST), Rd(op2_reg-IR_REG_FP_FIRST), Rd(op3_reg-IR_REG_FP_FIRST), eq
2474+ | fcsel Rd(def_reg-IR_REG_FP_FIRST), Rd(op2_reg-IR_REG_FP_FIRST), Rd(op3_reg-IR_REG_FP_FIRST), ne
24312475 } else {
2432- | fcsel Rs(def_reg-IR_REG_FP_FIRST), Rs(op2_reg-IR_REG_FP_FIRST), Rs(op3_reg-IR_REG_FP_FIRST), eq
2476+ | fcsel Rs(def_reg-IR_REG_FP_FIRST), Rs(op2_reg-IR_REG_FP_FIRST), Rs(op3_reg-IR_REG_FP_FIRST), ne
24332477 }
24342478 }
24352479
@@ -3851,6 +3895,12 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
38513895 val_insn->const_flags |= IR_CONST_EMIT;
38523896 | adr Rx(dst_reg), =>label
38533897 continue;
3898+ } else if (val_insn->op == IR_SYM || val_insn->op == IR_FUNC) {
3899+ void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
3900+ ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, val_insn->val.i32)) :
3901+ ir_resolve_sym_name(ir_get_str(ctx, val_insn->val.i32));
3902+ ir_emit_load_imm_int(ctx, IR_ADDR, dst_reg, (intptr_t)addr);
3903+ continue;
38543904 }
38553905 IR_ASSERT(val_insn->op == IR_ADDR || val_insn->op == IR_FUNC_ADDR);
38563906 } else if (ir_type_size[type] == 1) {
@@ -3875,7 +3925,11 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
38753925 | adr Rx(tmp_reg), =>label
38763926 | str Rx(tmp_reg), [sp, #stack_offset]
38773927 } else if (val_insn->op == IR_FUNC || val_insn->op == IR_SYM) {
3878- IR_ASSERT(0 && "sym");
3928+ void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
3929+ ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, val_insn->val.i32)) :
3930+ ir_resolve_sym_name(ir_get_str(ctx, val_insn->val.i32));
3931+ ir_emit_load_imm_int(ctx, IR_ADDR, tmp_reg, (intptr_t)addr);
3932+ | str Rx(tmp_reg), [sp, #stack_offset]
38793933 } else {
38803934 IR_ASSERT(tmp_reg != IR_REG_NONE);
38813935 ir_emit_load_imm_int(ctx, type, tmp_reg, val_insn->val.i64);
0 commit comments