Commit b101234a8e81fbe47249d2625445ffed37ddd49b
1 parent
26cc915c
Implement 64-bit constant loads
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4561 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
27 additions
and
15 deletions
tcg/sparc/tcg-target.c
... | ... | @@ -267,24 +267,37 @@ static inline void tcg_out_sethi(TCGContext *s, int ret, uint32_t arg) |
267 | 267 | tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10)); |
268 | 268 | } |
269 | 269 | |
270 | -static inline void tcg_out_movi(TCGContext *s, TCGType type, | |
271 | - int ret, tcg_target_long arg) | |
270 | +static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg) | |
271 | +{ | |
272 | + tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR); | |
273 | +} | |
274 | + | |
275 | +static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg) | |
272 | 276 | { |
273 | -#if defined(__sparc_v9__) && !defined(__sparc_v8plus__) | |
274 | - if (!check_fit_tl(arg, 32) && (arg & ~0xffffffff) != 0) | |
275 | - fprintf(stderr, "unimplemented %s with constant %ld\n", __func__, arg); | |
276 | -#endif | |
277 | 277 | if (check_fit_i32(arg, 13)) |
278 | - tcg_out32(s, ARITH_OR | INSN_RD(ret) | INSN_RS1(TCG_REG_G0) | | |
279 | - INSN_IMM13(arg)); | |
278 | + tcg_out_movi_imm13(s, ret, arg); | |
280 | 279 | else { |
281 | 280 | tcg_out_sethi(s, ret, arg); |
282 | 281 | if (arg & 0x3ff) |
283 | - tcg_out32(s, ARITH_OR | INSN_RD(ret) | INSN_RS1(ret) | | |
284 | - INSN_IMM13(arg & 0x3ff)); | |
282 | + tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR); | |
285 | 283 | } |
286 | 284 | } |
287 | 285 | |
286 | +static inline void tcg_out_movi(TCGContext *s, TCGType type, | |
287 | + int ret, tcg_target_long arg) | |
288 | +{ | |
289 | +#if defined(__sparc_v9__) && !defined(__sparc_v8plus__) | |
290 | + if (!check_fit_tl(arg, 32) && (arg & ~0xffffffffULL) != 0) { | |
291 | + // XXX ret may be I5, need another temp | |
292 | + tcg_out_movi_imm32(s, TCG_REG_I5, arg >> 32); | |
293 | + tcg_out_arithi(s, TCG_REG_I5, TCG_REG_I5, 32, SHIFT_SLLX); | |
294 | + tcg_out_movi_imm32(s, ret, arg); | |
295 | + tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_OR); | |
296 | + } else | |
297 | +#endif | |
298 | + tcg_out_movi_imm32(s, ret, arg); | |
299 | +} | |
300 | + | |
288 | 301 | static inline void tcg_out_ld_raw(TCGContext *s, int ret, |
289 | 302 | tcg_target_long arg) |
290 | 303 | { |
... | ... | @@ -296,15 +309,14 @@ static inline void tcg_out_ld_raw(TCGContext *s, int ret, |
296 | 309 | static inline void tcg_out_ld_ptr(TCGContext *s, int ret, |
297 | 310 | tcg_target_long arg) |
298 | 311 | { |
312 | + if (!check_fit_tl(arg, 10)) | |
313 | + tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ffULL); | |
299 | 314 | #if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
300 | - if (!check_fit_tl(arg, 32) && (arg & ~0xffffffff) != 0) | |
301 | - fprintf(stderr, "unimplemented %s with offset %ld\n", __func__, arg); | |
302 | - if (!check_fit_i32(arg, 13)) | |
303 | - tcg_out_sethi(s, ret, arg); | |
304 | 315 | tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) | |
305 | 316 | INSN_IMM13(arg & 0x3ff)); |
306 | 317 | #else |
307 | - tcg_out_ld_raw(s, ret, arg); | |
318 | + tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) | | |
319 | + INSN_IMM13(arg & 0x3ff)); | |
308 | 320 | #endif |
309 | 321 | } |
310 | 322 | ... | ... |