@@ -463,6 +463,22 @@ int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constrain
463
463
}
464
464
flags = IR_USE_SHOULD_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG;
465
465
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;
466
482
case IR_COPY_INT:
467
483
case IR_COPY_FP:
468
484
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)
2138
2154
case IR_GT:
2139
2155
| cset Rw(def_reg), gt
2140
2156
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;
2141
2169
}
2142
2170
if (IR_REG_SPILLED(ctx->regs[def][0])) {
2143
2171
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
2212
2240
ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
2213
2241
if (true_block == next_block) {
2214
2242
/* 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
+ }
2216
2248
true_block = false_block;
2217
2249
false_block = 0;
2218
2250
} 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
2276
2308
case IR_GT:
2277
2309
| bgt =>true_block
2278
2310
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;
2279
2323
// case IR_ULT: fprintf(stderr, "\tjb .LL%d\n", true_block); break;
2280
2324
// case IR_UGE: fprintf(stderr, "\tjae .LL%d\n", true_block); break;
2281
2325
// 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)
2421
2465
2422
2466
if (IR_IS_TYPE_INT(type)) {
2423
2467
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
2425
2469
} 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
2427
2471
}
2428
2472
} else{
2429
2473
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
2431
2475
} 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
2433
2477
}
2434
2478
}
2435
2479
@@ -3851,6 +3895,12 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
3851
3895
val_insn->const_flags |= IR_CONST_EMIT;
3852
3896
| adr Rx(dst_reg), =>label
3853
3897
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;
3854
3904
}
3855
3905
IR_ASSERT(val_insn->op == IR_ADDR || val_insn->op == IR_FUNC_ADDR);
3856
3906
} 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
3875
3925
| adr Rx(tmp_reg), =>label
3876
3926
| str Rx(tmp_reg), [sp, #stack_offset]
3877
3927
} 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]
3879
3933
} else {
3880
3934
IR_ASSERT(tmp_reg != IR_REG_NONE);
3881
3935
ir_emit_load_imm_int(ctx, type, tmp_reg, val_insn->val.i64);
0 commit comments