On 02/10/2016 03:50 AM, James Hogan wrote:
I think ret and 0 are the wrong way around here. You're putting 0 in rs
(the destination register), which causes a seg fault.
OUT: [size=56]
0xfff30b0064: lw s1,-8(s0)
0xfff30b0068: bnezalc zero,s1,0xfff30b0090
0xfff30b006c: nop
0xfff30b0070: j 0xfff0000000
0xfff30b0074: nop
0xfff30b0078: lui s1,0xbfc0
0xfff30b007c: ori s1,s1,0x580
0xfff30b0080: sd s1,256(s0)
0xfff30b0084: aluipc zero,0xfeb7
0xfff30b0088: j 0xfff30b0034
0xfff30b008c: ori v0,v0,0x4010
0xfff30b0090: aluipc zero,0xfeb7
0xfff30b0094: j 0xfff30b0034
0xfff30b0098: ori v0,v0,0x4013
Cheers
James
+ } else {
+ TCGReg in = TCG_REG_ZERO;
+ tcg_target_long tmp = (int16_t)arg;
+
+ /* The R6 manual recommends construction of immediates in
+ order of low to high (ADDI, AUI, DAHI, DATI) in order
+ to simplify hardware recognizing these sequences. */
+
+ if (tmp) {
+ tcg_out_opc_imm(s, OPC_ADDIU, ret, in, tmp);
+ in = ret;
+ }
+ arg = (arg - tmp) >> 16;
+ tmp = (int16_t)arg;
+
+ /* Note that DAHI and DATI only have one register operand,
+ and are thus we must put a zero low part in place. Also
+ note that we already eliminated simple 32-bit constants
+ so we know this must happen. */
+ if (tmp || in != ret) {
+ tcg_out_opc_imm(s, OPC_AUI, ret, in, tmp);
+ }
+ arg = (arg - tmp) >> 16;
+ tmp = (int16_t)arg;
+
+ if (tmp) {
+ tcg_out_opc_imm(s, OPC_DAHI, ret, 0, tmp);
+ }
+ arg = (arg - tmp) >> 16;
+ tcg_debug_assert(arg == (int16_t)arg);
+
+ if (arg) {
+ tcg_out_opc_imm(s, OPC_DATI, ret, 0, arg);
Same mistake here for DAHI/DATI.
r~