On 11/15/18 11:36 PM, Alistair Francis wrote: > +static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1, > + TCGReg arg2, TCGLabel *l) > +{ > + RISCVInsn op = tcg_brcond_to_riscv[cond].op; > + bool swap = tcg_brcond_to_riscv[cond].swap; > + > + tcg_out_opc_branch(s, op, swap ? arg2 : arg1, swap ? arg1 : arg2, 0);
You might want to tcg_debug_assert(op != 0) here. > + if (l->has_value) { > + reloc_sbimm12(s->code_ptr - 1, l->u.value_ptr); I'm concerned about the conditional branch range. +-4K isn't much to work with. The minimum we have for other hosts is +-32K. We have two options: (1) greatly reduce the max size of the TB for this host; (2) be prepared to emit a 2 insn sequence: conditional branch across unconditional branch, with forward branches that turn out to be small patched with a nop. FWIW, the first case would be done via modification of tcg_op_buf_full. You might have to go as low as 500 opcodes, I'm not sure. > +static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target) > +{ > + ptrdiff_t offset = tcg_pcrel_diff(s, target); > + tcg_debug_assert(offset == sextract64(offset, 0, 26)); > + tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset); > +} > + > +static inline void tcg_out_goto_long(TCGContext *s, tcg_insn_unit *target) > +{ > + ptrdiff_t offset = tcg_pcrel_diff(s, target); > + > + if (offset == sextract64(offset, 0, 26)) { > + tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset); > + } else { > + tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP0, (intptr_t)target); > + tcg_out_opc_jump(s, OPC_JAL, TCG_REG_TMP0, 0); > + } > +} How are these to be used? I guess I'll find out... > +static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail) > +{ > + TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA; > + ptrdiff_t offset = tcg_pcrel_diff(s, arg); > + if (offset == sextract32(offset, 1, 20) << 1) { sextract64. > + /* short jump: -2097150 to 2097152 */ > + tcg_out_opc_jump(s, OPC_JAL, link, offset); > + } else if (TCG_TARGET_REG_BITS == 32 || > + offset == sextract32(offset, 1, 31) << 1) { sextract64. > + /* long jump: -2147483646 to 2147483648 */ > + tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0); > + tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, 0); > + reloc_call(s->code_ptr - 2, arg); > + } else if (TCG_TARGET_REG_BITS == 64) { > + /* far jump: 64-bit */ > + tcg_target_long imm = sextract32((tcg_target_long)arg, 0, 12); > + tcg_target_long base = (tcg_target_long)arg - imm; > + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, base); > + tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, imm); r~