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