[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH for-2.5 28/30] m68k: shift/rotate bytes and word
From: |
Richard Henderson |
Subject: |
Re: [Qemu-devel] [PATCH for-2.5 28/30] m68k: shift/rotate bytes and words |
Date: |
Wed, 12 Aug 2015 12:11:59 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 |
On 08/09/2015 01:13 PM, Laurent Vivier wrote:
> +#define HELPER_SHL(type, bits) \
> +uint32_t HELPER(glue(glue(shl, bits), _cc))(CPUM68KState *env, \
> + uint32_t val, uint32_t shift) \
> +{ \
> + type result; \
> + uint32_t cf; \
> + shift &= 63; \
> + if (shift == 0) { \
> + result = (type)val; \
> + cf = 0; \
> + } else if (shift < bits) { \
> + result = (type)val << shift; \
> + cf = ((type)val >> (bits - shift)) & 1; \
> + } else if (shift == bits) { \
> + result = 0; \
> + cf = val & 1; \
> + } else { \
> + result = 0; \
> + cf = 0; \
> + } \
Perhaps this would be cleaner to simply operate on a 64-bit type.
uint64_t res = (type)val;
res <<= shift & 63;
cf = (res >> bits) & 1;
For shift == 0, we've not set bit BITS, so it's zero.
For shift <= BITS, we've obviously got the correct data.
For shift > BITS, we've shifted val all the way past and again have zero.
> +#define HELPER_SHR(type, bits) \
> +uint32_t HELPER(glue(glue(shr, bits), _cc))(CPUM68KState *env, \
> + uint32_t val, uint32_t shift) \
> +{ \
> + type result; \
> + uint32_t cf; \
> + shift &= 63; \
> + if (shift == 0) { \
> + result = (type)val; \
> + cf = 0; \
> + } else if (shift < bits) { \
> + result = (type)val >> shift; \
> + cf = ((type)val >> (shift - 1)) & 1; \
> + } else if (shift == bits) { \
> + result = 0; \
> + cf = (type)val >> (bits - 1); \
> + } else { \
> + result = 0; \
> + cf = 0; \
> + } \
Similarly.
> +#define HELPER_SAL(type, bits) \
> +uint32_t HELPER(glue(glue(sal, bits), _cc))(CPUM68KState *env, \
> + uint32_t val, uint32_t shift) \
> +{ \
> + type result; \
> + uint32_t cf; \
> + uint32_t vf; \
> + uint32_t m; \
> + shift &= 63; \
> + if (shift == 0) { \
> + vf = 0; \
> + } else if (shift < bits) { \
> + m = ((1llu << (shift + 1)) - 1) << (bits - shift - 1); \
> + vf = (val & m) != m && (val & m) != 0; \
> + } else { \
> + m = (1llu << bits) - 1; \
> + vf = (val & m) != 0; \
> + } \
This computation of VF seems overly complex. It's just
(type)(val ^ result) < 0
for all cases.
> +DISAS_INSN(shift8_im)
> +DISAS_INSN(shift16_im)
> DISAS_INSN(shift_im)
...
> +DISAS_INSN(shift8_reg)
> +DISAS_INSN(shift16_reg)
> DISAS_INSN(shift_reg)
...
> +DISAS_INSN(shift_mem)
Surely some code could be shared here...
r~
- Re: [Qemu-devel] [PATCH for-2.5 24/30] m68k: add DBcc and Scc (memory operand), (continued)
- [Qemu-devel] [PATCH for-2.5 28/30] m68k: shift/rotate bytes and words, Laurent Vivier, 2015/08/09
- Re: [Qemu-devel] [PATCH for-2.5 28/30] m68k: shift/rotate bytes and words,
Richard Henderson <=
- [Qemu-devel] [PATCH for-2.5 26/30] m68k: add mull/divl, Laurent Vivier, 2015/08/09
- [Qemu-devel] [PATCH for-2.5 29/30] m68k: add rol/rox/ror/roxr, Laurent Vivier, 2015/08/09
- [Qemu-devel] [PATCH for-2.5 30/30] m68k: add bitfield instructions, Laurent Vivier, 2015/08/09
- Re: [Qemu-devel] [PATCH for-2.5 00/30] 680x0 instructions emulation, Richard Henderson, 2015/08/12