On Sat, Dec 19, 2009 at 5:47 PM, Richard Henderson <r...@twiddle.net> wrote: > On 12/19/2009 02:31 AM, Blue Swirl wrote: >>> >>> static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t >>> arg) >>> { >>> - if (check_fit_tl(arg, 12)) >>> + if (check_fit_tl(arg, 13)) >>> tcg_out_movi_imm13(s, ret, arg); >> >> IIRC sign extension prevents this. > > Pardon? check_fit_tl checks a signed value, the OR opcode provides one. > Where's the conflict?
Long time ago I tried the same change, but the generated code was not correct. But now it seems to work. >>> - if (const_arg2&& arg2 == 0) >>> - /* orcc %g0, r, %g0 */ >>> - tcg_out_arith(s, TCG_REG_G0, TCG_REG_G0, arg1, ARITH_ORCC); >>> - else >>> - /* subcc r1, r2, %g0 */ >>> - tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC); >>> - tcg_out_branch_i32(s, tcg_cond_to_bcond[cond], label_index); >>> + tcg_out_cmp(s, arg1, arg2, const_arg2); >> >> What's wrong with 'orcc' (produces the synthetic instruction 'tst')? > > What result does "orcc" give that isn't produced by "subcc"? Unlike i386 > where "test x,x" is one byte smaller than "cmp $0,x", it seems to me there's > no reason to distingish the arg2 == constant zero case on sparc. Maybe it's faster on real CPUs. On my machine I don't see any difference. I timed the following program: #include <stdio.h> #include <stdlib.h> #define N 100000000 int main(int argc, char **argv) { unsigned int i; if (atoi(argv[1])) { for (i = 0; i < N; i++) { asm volatile ("cmp %g1, 0"); } } else { for (i = 0; i < N; i++) { asm volatile ("tst %g1"); } } return 0; }