Revision 0a878c47 tcg/ppc/tcg-target.c

b/tcg/ppc/tcg-target.c
388 388
    else {
389 389
        tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
390 390
        if (arg & 0xffff)
391
            tcg_out32 (s, ORI | RT (ret) | RA (ret) | (arg & 0xffff));
391
            tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
392 392
    }
393 393
}
394 394

  
......
939 939
            tcg_out32 (s, op | RA (arg1) | RB (arg2));
940 940
    }
941 941

  
942
    if (l->has_value) {
943
        tcg_target_long disp;
944

  
945
        disp = (tcg_target_long) s->code_ptr - l->u.value;
946
        if (disp != (int16_t) disp)
947
            tcg_abort ();
948

  
942
    if (l->has_value)
949 943
        tcg_out32 (s, tcg_to_bc[cond] | reloc_pc14_val (s->code_ptr,
950 944
                                                        l->u.value));
951
    }
952 945
    else {
953
        tcg_out32 (s, tcg_to_bc[cond]);
946
        uint16_t val = *(uint16_t *) &s->code_ptr[2];
947

  
948
        /* Thanks to Andrzej Zaborowski */
949
        tcg_out32 (s, tcg_to_bc[cond] | (val & 0xfffc));
954 950
        tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
955 951
    }
956 952
}
......
1029 1025
    case INDEX_op_goto_tb:
1030 1026
        if (s->tb_jmp_offset) {
1031 1027
            /* direct jump method */
1032
            uint32_t val;
1033
            uint16_t *p;
1034 1028

  
1035 1029
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1036
            /* Thanks to Andrzej Zaborowski for this */
1037
            val = *(uint32_t *) s->code_ptr & 0x3fffffc;
1038

  
1039
            tcg_out32 (s, B | val);
1040

  
1041
            /* For branches outside of LL range
1042
               This must be in concord with tb_set_jmp_target1 */
1043
            p = (uint16_t *) s->code_ptr;
1044
            p[0] = (ADDIS | RT (0) | RA (0)) >> 16;
1045
            p[2] = (ORI | RT (0) | RA (0)) >> 16;
1046
            s->code_ptr += 8;
1047

  
1048
            tcg_out32 (s, MTSPR | RS (0) | CTR);
1049
            tcg_out32 (s, BCCTR | BO_ALWAYS);
1030
            s->code_ptr += 16;
1050 1031
        }
1051 1032
        else {
1052 1033
            tcg_abort ();
......
1061 1042
                tcg_out_b (s, 0, l->u.value);
1062 1043
            }
1063 1044
            else {
1064
                tcg_out32 (s, B);
1045
                uint32_t val = *(uint32_t *) s->code_ptr;
1046

  
1047
                /* Thanks to Andrzej Zaborowski */
1048
                tcg_out32 (s, B | (val & 0x3fffffc));
1065 1049
                tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
1066 1050
            }
1067 1051
        }
......
1222 1206
    case INDEX_op_div2_i32:
1223 1207
        if (args[0] == args[2] || args[0] == args[3]) {
1224 1208
            tcg_out32 (s, DIVW | TAB (0, args[2], args[3]));
1209
            tcg_out32 (s, MTSPR | RS (0) | CTR);
1225 1210
            tcg_out32 (s, MULLW | TAB (0, 0, args[3]));
1226
            tcg_out32 (s, SUBF | TAB (0, 0, args[2]));
1227
            tcg_out32 (s, DIVW | TAB (args[0], args[2], args[3]));
1228
            tcg_out_mov (s, args[1], 0);
1211
            tcg_out32 (s, SUBF | TAB (args[1], 0, args[2]));
1212
            tcg_out32 (s, MFSPR | RT (args[0]) | CTR);
1229 1213
        }
1230 1214
        else {
1231 1215
            tcg_out32 (s, DIVW | TAB (args[0], args[2], args[3]));
......
1236 1220
    case INDEX_op_divu2_i32:
1237 1221
        if (args[0] == args[2] || args[0] == args[3]) {
1238 1222
            tcg_out32 (s, DIVWU | TAB (0, args[2], args[3]));
1223
            tcg_out32 (s, MTSPR | RS (0) | CTR);
1239 1224
            tcg_out32 (s, MULLW | TAB (0, 0, args[3]));
1240
            tcg_out32 (s, SUBF | TAB (0, 0, args[2]));
1241
            tcg_out32 (s, DIVWU | TAB (args[0], args[2], args[3]));
1242
            tcg_out_mov (s, args[1], 0);
1225
            tcg_out32 (s, SUBF | TAB (args[1], 0, args[2]));
1226
            tcg_out32 (s, MFSPR | RT (args[0]) | CTR);
1243 1227
        }
1244 1228
        else {
1245 1229
            tcg_out32 (s, DIVWU | TAB (args[0], args[2], args[3]));

Also available in: Unified diff