All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bryce Lanham <blanham@gmail.com>
To: qemu-devel@nongnu.org
Cc: Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PATCH 023/111] m68k: add variable offset/width to bitfield_reg/bitfield_mem
Date: Wed, 17 Aug 2011 15:46:28 -0500	[thread overview]
Message-ID: <1313614076-28878-24-git-send-email-blanham@gmail.com> (raw)
In-Reply-To: <1313614076-28878-1-git-send-email-blanham@gmail.com>

From: Laurent Vivier <laurent@vivier.eu>

This patch allows bitfield instructions to read bit offset and field
size from a register instead of an immediat value.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/helper.c    |   50 +++++
 target-m68k/helpers.h   |    2 +
 target-m68k/translate.c |  515 +++++++++++++++++++++++------------------------
 3 files changed, 299 insertions(+), 268 deletions(-)

diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index d6c92bf..fd9867d 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -535,6 +535,8 @@ uint32_t HELPER(bfffo)(uint32_t arg, uint32_t width)
 uint32_t HELPER(rol32)(uint32_t val, uint32_t shift)
 {
     uint32_t result;
+    if (shift == 0 || shift == 32)
+        return val;
     result = (val << shift) | (val >> (32 - shift));
     return result;
 }
@@ -542,6 +544,8 @@ uint32_t HELPER(rol32)(uint32_t val, uint32_t shift)
 uint32_t HELPER(ror32)(uint32_t val, uint32_t shift)
 {
     uint32_t result;
+    if (shift == 0 || shift == 32)
+        return val;
     result = (val >> shift) | (val << (32 - shift));
     return result;
 }
@@ -1188,3 +1192,49 @@ void HELPER(set_mac_extu)(CPUState *env, uint32_t val, uint32_t acc)
     res |= (uint64_t)(val & 0xffff0000) << 16;
     env->macc[acc + 1] = res;
 }
+
+/* load from a bitfield */
+
+uint64_t HELPER(bitfield_load)(uint32_t addr, uint32_t offset, uint32_t width)
+{
+    uint8_t data[8];
+    uint64_t bitfield;
+    int size;
+    int i;
+
+    size = (offset + width + 7) >> 3;
+#if defined(CONFIG_USER_ONLY)
+    cpu_memory_rw_debug(NULL, (target_ulong)addr, data, size, 0);
+#else
+    cpu_physical_memory_rw(addr, data, size, 0);
+#endif
+
+    bitfield = data[0];
+    for (i = 1; i < 8; i++)
+        bitfield = (bitfield << 8) | data[i];
+
+    return bitfield;
+}
+
+/* store to a bitfield */
+
+void HELPER(bitfield_store)(uint32_t addr, uint32_t offset, uint32_t width,
+                            uint64_t bitfield)
+{
+    uint8_t data[8];
+    int size;
+    int i;
+
+    size = (offset + width + 7) >> 3;
+
+    for (i = 0; i < 8; i++) {
+        data[7 - i] = bitfield;
+        bitfield >>= 8;
+    }
+
+#if defined(CONFIG_USER_ONLY)
+    cpu_memory_rw_debug(NULL, (target_ulong)addr, data, size, 1);
+#else
+    cpu_physical_memory_rw(addr, data, size, 1);
+#endif
+}
diff --git a/target-m68k/helpers.h b/target-m68k/helpers.h
index 949d5d5..d71ed26 100644
--- a/target-m68k/helpers.h
+++ b/target-m68k/helpers.h
@@ -78,4 +78,6 @@ DEF_HELPER_3(set_mac_extu, void, env, i32, i32)
 DEF_HELPER_2(flush_flags, void, env, i32)
 DEF_HELPER_1(raise_exception, void, i32)
 
+DEF_HELPER_3(bitfield_load, i64, i32, i32, i32);
+DEF_HELPER_4(bitfield_store, void, i32, i32, i32, i64);
 #include "def-helper.h"
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 334681b..fa67ff9 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2386,263 +2386,225 @@ DISAS_INSN(rotate_mem)
     DEST_EA(insn, OS_WORD, dest, &addr);
 }
 
+static void bitfield_param(uint16_t ext, TCGv *offset, TCGv *width, TCGv *mask)
+{
+    TCGv tmp;
+
+    /* offset */
+
+    if (ext & 0x0800) {
+        *offset = DREG(ext, 6);
+    } else {
+        *offset = tcg_temp_new_i32();
+        tcg_gen_movi_i32(*offset, (ext >> 6) & 31);
+    }
+
+    /* width */
+
+    if (ext & 0x0020) {
+        *width = DREG(ext, 0);
+        tcg_gen_subi_i32(*width, *width, 1);
+        tcg_gen_andi_i32(*width, *width, 31);
+        tcg_gen_addi_i32(*width, *width, 1);
+    } else {
+        *width = tcg_temp_new_i32();
+        tcg_gen_movi_i32(*width, ((ext - 1) & 31) + 1);
+    }
+
+    /* mask */
+
+    tmp = tcg_temp_new_i32();
+    tcg_gen_sub_i32(tmp, tcg_const_i32(32), *width);
+    *mask = tcg_temp_new_i32();
+    tcg_gen_shl_i32(*mask, tcg_const_i32(0xffffffff), tmp);
+}
+
 DISAS_INSN(bitfield_reg)
 {
     uint16_t ext;
     TCGv tmp;
     TCGv tmp1;
     TCGv reg;
-    int offset;
-    int width;
+    TCGv offset;
+    TCGv width;
     int op;
     TCGv reg2;
-    uint32_t mask;
+    TCGv mask;
 
     reg = DREG(insn, 0);
     op = (insn >> 8) & 7;
     ext = lduw_code(s->pc);
     s->pc += 2;
-    if ((ext & 0x820) == 0) {
-       /* constant offset and width */
-       offset = (ext >> 6) & 31;
-       width = (ext & 31);
-       if (width == 0)
-           width = 32;
-       reg2 = DREG(ext, 12);
-       mask = 0xffffffff << (32 - width);
-       if (offset > 0)
-           mask = (mask >> offset) | (mask << (32 - offset));
-       tmp = tcg_temp_new_i32();
-       tcg_gen_andi_i32(tmp, reg, mask);
-       if (offset > 0) {
-           tmp1 = tcg_temp_new_i32();
-           gen_helper_rol32(tmp1, tmp, tcg_const_i32(offset));
-       } else
-           tmp1 = tmp;
-       gen_logic_cc(s, tmp1);
-       switch (op) {
-       case 0: /* bftst */
-           break;
-       case 1: /* bfextu */
-           if (offset + width != 32)
-               gen_helper_rol32(reg2, tmp, tcg_const_i32((offset + width) & 31));
-           else
-               tcg_gen_mov_i32(reg2, tmp);
-           break;
-       case 2: /* bfchg */
-           tcg_gen_xor_i32(reg, reg, tcg_const_i32(mask));
-           break;
-       case 3: /* bfexts */
-           if (offset > 0)
-               gen_helper_rol32(reg2, tmp, tcg_const_i32(offset));
-           if (width < 32)
-               tcg_gen_sari_i32(reg2, reg2, 32 - width);
-           break;
-       case 4: /* bfclr */
-	   tcg_gen_and_i32(reg, reg, tcg_const_i32(mask));
-           break;
-       case 5: /* bfffo */
-           if (offset > 0)
-               gen_helper_rol32(reg2, tmp, tcg_const_i32(offset));
-           gen_helper_bfffo(tmp, tmp, tcg_const_i32(width));
-           tcg_gen_addi_i32(reg2, tmp, offset);
-           break;
-       case 6: /* bfset */
-           tcg_gen_ori_i32(reg, reg, mask);
-           break;
-       case 7: /* bfins */
-           if (width == 32) {
-               if (offset > 0)
-                   gen_helper_ror32(reg, reg2, tcg_const_i32(offset));
-               else
-                   tcg_gen_mov_i32(reg, reg2);
-           } else {
-               tcg_gen_andi_i32(tmp, reg2, (1u << width) - 1);
-               if (offset + width != 32)
-                   gen_helper_ror32(tmp, tmp, tcg_const_i32((offset + width) & 31));
-               tcg_gen_andi_i32(reg, reg, ~mask);
-               tcg_gen_or_i32(reg, reg, tmp);
-           }
-           break;
-       }
-       return;
-    }
-    /* Not yet implemented */
-    gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
-}
 
-/* Generate a load from a bitfield.  */
-static void gen_bitfield_load(DisasContext *s, TCGv addr, int endpos,
-                             TCGv *val1, TCGv *val2)
-{
-    TCGv tmp;
+    bitfield_param(ext, &offset, &width, &mask);
 
-    if (endpos <= 8)
-       *val1 = gen_load(s, OS_BYTE, addr, 0);
-    else if (endpos <= 24) {
-       *val1 = gen_load(s, OS_WORD, addr, 0);
-       if (endpos > 16) {
-           tmp = tcg_temp_new_i32();
-           tcg_gen_addi_i32(tmp, addr, 2);
-           *val2 = gen_load(s, OS_BYTE, tmp, 0);
-       }
-    } else {
-       *val1 = gen_load(s, OS_LONG, addr, 0);
-       if (endpos > 32) {
-           tmp = tcg_temp_new_i32();
-           tcg_gen_addi_i32(tmp, addr, 4);
-           *val2 = gen_load(s, OS_BYTE, tmp, 0);
-       }
-    }
-}
+    if (ext & 0x0800)
+        tcg_gen_andi_i32(offset, offset, 31);
+    gen_helper_ror32(mask, mask, offset);
 
-/* Generate a store to a bitfield.  */
-static void gen_bitfield_store(DisasContext *s, TCGv addr, int endpos,
-                              TCGv val1, TCGv val2)
-{
-    TCGv tmp;
+    /* reg & mask */
 
-    if (endpos <= 8)
-       gen_store(s, OS_BYTE, addr, val1);
-    else if (endpos <= 24) {
-       gen_store(s, OS_WORD, addr, val1);
-       if (endpos > 16) {
-           tmp = tcg_temp_new_i32();
-           tcg_gen_addi_i32(tmp, addr, 2);
-           gen_store(s, OS_BYTE, tmp, val2);
-       }
-    } else {
-       gen_store(s, OS_LONG, addr, val1);
-       if (endpos > 32) {
-           tmp = tcg_temp_new_i32();
-           tcg_gen_addi_i32(tmp, addr, 4);
-           gen_store(s, OS_BYTE, tmp, val2);
-       }
+    tmp = tcg_temp_new_i32();
+    tcg_gen_and_i32(tmp, reg, mask);
+
+    tmp1 = tcg_temp_new_i32();
+    gen_helper_rol32(tmp1, tmp, offset);
+    gen_logic_cc(s, tmp1);
+
+    reg2 = DREG(ext, 12);
+    switch (op) {
+    case 0: /* bftst */
+        break;
+    case 1: /* bfextu */
+        tcg_gen_add_i32(tmp1, offset, width);
+        tcg_gen_andi_i32(tmp1, tmp1, 31);
+        gen_helper_rol32(reg2, tmp, tmp1);
+        break;
+    case 2: /* bfchg */
+        tcg_gen_xor_i32(reg, reg, mask);
+        break;
+    case 3: /* bfexts */
+        gen_helper_rol32(reg2, tmp, offset);
+        tcg_gen_sub_i32(width, tcg_const_i32(32), width);
+        tcg_gen_sar_i32(reg2, reg2, width);
+        break;
+    case 4: /* bfclr */
+        tcg_gen_and_i32(reg, reg, mask);
+        break;
+    case 5: /* bfffo */
+        gen_helper_rol32(reg2, tmp, offset);
+        gen_helper_bfffo(tmp, tmp, width);
+        tcg_gen_add_i32(reg2, tmp, offset);
+        break;
+    case 6: /* bfset */
+        tcg_gen_or_i32(reg, reg, mask);
+        break;
+    case 7: /* bfins */
+        tcg_gen_shl_i32(tmp1, tcg_const_i32(1), width);
+        tcg_gen_subi_i32(tmp1, tmp1, 1);
+        tcg_gen_and_i32(tmp, reg2, tmp1);
+        tcg_gen_add_i32(tmp1, offset, width);
+        tcg_gen_andi_i32(tmp1, tmp1, 31);
+        gen_helper_ror32(tmp, tmp, tmp1);
+        tcg_gen_not_i32(mask, mask);
+        tcg_gen_and_i32(reg, reg, mask);
+        tcg_gen_or_i32(reg, reg, tmp);
+        break;
     }
 }
 
-static TCGv gen_bitfield_cc(DisasContext *s, int offset, int width,
-                          TCGv val1, TCGv val2)
+static TCGv gen_bitfield_cc(DisasContext *s,
+                            TCGv offset, TCGv mask_cc, TCGv_i64 bitfield)
 {
     TCGv dest;
-    TCGv tmp;
+    TCGv_i64 tmp64;
 
+    /* move bitfield to a 32bit */
+
+    tmp64 = tcg_temp_new_i64();
+
+    tcg_gen_extu_i32_i64(tmp64, offset);
+
+    /* tmp64 = bitfield << offset */
+
+    tcg_gen_shl_i64(tmp64, bitfield, tmp64);
+
+    /* tmp = (bitfield << offset) >> 32 */
+
+    tcg_gen_shri_i64(tmp64, bitfield, 32ULL);
     dest = tcg_temp_new_i32();
+    tcg_gen_trunc_i64_i32(dest, tmp64);
 
-    if (offset + width <= 8)
-       tcg_gen_shli_i32(dest, val1, 24 + offset);
-    else if (offset + width <= 24) {
-       tcg_gen_shli_i32(dest, val1, 16 + offset);
-       if (offset + width > 16) {
-           tmp = tcg_temp_new_i32();
-           tcg_gen_shli_i32(tmp, val2, 8 + offset);
-           tcg_gen_or_i32(dest, dest, tmp);
-       }
-    } else {
-       tcg_gen_shli_i32(dest, val1, offset);
-       if (offset + width > 32) {
-           tmp = tcg_temp_new_i32();
-           tcg_gen_shri_i32(tmp, val2, offset);
-           tcg_gen_or_i32(dest, dest, tmp);
-       }
-    }
-    tcg_gen_andi_i32(dest, dest, 0xffffffff << (32 - width));
+    /* compute cc */
+
+    tcg_gen_and_i32(dest, dest, mask_cc);
     gen_logic_cc(s, dest);
+
     return dest;
 }
 
-static void gen_bitfield_op(int offset, int width, int op, TCGv val1, TCGv val2)
-{
-    uint32_t mask1;
-    uint32_t mask2;
-    int endpos = offset + width;
-
-    if (endpos <= 8) {
-       mask1 = (0xff >> offset) & (0xff << (8 - endpos));
-       mask2 = 0;
-    } else if (endpos <= 16) {
-       mask1 = (0xffff >> offset) & (0xffff << (16 - endpos));
-       mask2 = 0;
-    } else if (endpos <= 24) {
-       mask1 = 0xffffff >> offset;
-       mask2 = 0xff & (0xff << (24 - endpos));
-    } else if (endpos <= 32) {
-       mask1 = (0xffffffff >> offset) & (0xffffffff << (32 - endpos));
-       mask2 = 0;
-    } else {
-       mask1 = 0xffffffff >> offset;
-       mask2 = 0xff & (0xff << (40 - endpos));
-    }
-    switch (op) {
-    case 2:                    /* bfchg */
-       tcg_gen_xori_i32(val1, val1, mask1);
-       if (mask2)
-           tcg_gen_xori_i32(val2, val2, mask2);
-       break;
-    case 4:                    /* bfclr */
-       tcg_gen_andi_i32(val1, val1, ~mask1);
-       if (mask2)
-           tcg_gen_andi_i32(val2, val2, ~mask2);
-       break;
-    case 6:                    /* bfset */
-       tcg_gen_ori_i32(val1, val1, mask1);
-       if (mask2)
-           tcg_gen_ori_i32(val2, val2, mask2);
-       break;
-    }
-}
-
-static void gen_bitfield_ins(int offset, int width, TCGv src,
-                            TCGv val1, TCGv val2)
+static TCGv_i64 gen_bitfield_mask(TCGv offset, TCGv width)
 {
     TCGv tmp;
-    int endpos = offset + width;
+    TCGv_i64 mask;
+    TCGv_i64 shift;
+
+    mask = tcg_temp_new_i64();
+
+    /* mask = (1u << width) - 1; */
+
+    tcg_gen_extu_i32_i64(mask, width);
+    tcg_gen_shl_i64(mask, tcg_const_i64(1), mask);
+    tcg_gen_subi_i64(mask, mask, 1);
+
+    /* shift = 64 - (width + offset); */
 
     tmp = tcg_temp_new_i32();
-    if (width < 32) {
-       tcg_gen_andi_i32(tmp, src, (1u << width) - 1);
-    } else
-       tcg_gen_mov_i32(tmp, src);
-    if (endpos <= 8) {
-       if (endpos < 8)
-           tcg_gen_shli_i32(tmp, tmp, 8 - endpos);
-       tcg_gen_or_i32(val1, val1, tmp);
-    } else if (endpos <= 16) {
-       if (endpos < 16)
-           tcg_gen_shli_i32(tmp, tmp, 16 - endpos);
-       tcg_gen_or_i32(val1, val1, tmp);
-    } else if (endpos <= 24) {
-       tcg_gen_shri_i32(tmp, tmp, endpos - 16);
-       tcg_gen_or_i32(val1, val1, tmp);
-       tcg_gen_andi_i32(tmp, src, (1u << (endpos - 16)) - 1);
-       if (endpos < 24)
-           tcg_gen_shli_i32(tmp, tmp, 24 - endpos);
-       tcg_gen_or_i32(val2, val2, tmp);
-    } else if (endpos <= 32) {
-       if (endpos < 32)
-           tcg_gen_shli_i32(tmp, tmp, 32 - endpos);
-       tcg_gen_or_i32(val1, val1, tmp);
-    } else {
-       tcg_gen_shri_i32(tmp, tmp, endpos - 32);
-       tcg_gen_or_i32(val1, val1, tmp);
-       tcg_gen_andi_i32(tmp, src, (1u << (endpos - 32)) - 1);
-       tcg_gen_shri_i32(tmp, tmp, 32 - endpos);
-       tcg_gen_or_i32(val2, val2, tmp);
-    }
+    tcg_gen_add_i32(tmp, offset, width);
+    tcg_gen_sub_i32(tmp, tcg_const_i32(64), tmp);
+    shift = tcg_temp_new_i64();
+    tcg_gen_extu_i32_i64(shift, tmp);
+
+    /* mask <<= shift */
+
+    tcg_gen_shl_i64(mask, mask, shift);
+
+    return mask;
+}
+
+static void gen_bitfield_ins(TCGv offset, TCGv width, TCGv src,
+                                 TCGv_i64 val)
+{
+    TCGv_i64 insert;
+    TCGv_i64 shift;
+    TCGv tmp;
+
+    tmp = tcg_temp_new_i32();
+
+    /* tmp = (1u << width) - 1; */
+
+    tcg_gen_shl_i32(tmp, tcg_const_i32(1), width);
+    tcg_gen_subi_i32(tmp, tmp, 1);
+
+    /* tmp = tmp & src; */
+
+    tcg_gen_and_i32(tmp, tmp, src);
+
+    /* insert = (i64)tmp; */
+
+    insert = tcg_temp_new_i64();
+    tcg_gen_extu_i32_i64(insert, tmp);
+
+    /* tmp = 64 - (width + offset); */
+
+    tcg_gen_add_i32(tmp, offset, width);
+    tcg_gen_sub_i32(tmp, tcg_const_i32(64), tmp);
+    shift = tcg_temp_new_i64();
+    tcg_gen_extu_i32_i64(shift, tmp);
+
+    /* insert <<= shift */
+
+    tcg_gen_shl_i64(insert, insert, shift);
+
+    /* val |=  select */
+
+    tcg_gen_or_i64(val, val, insert);
 }
 
 DISAS_INSN(bitfield_mem)
 {
     uint16_t ext;
+    int op;
+    TCGv_i64 bitfield;
+    TCGv_i64 mask_bitfield;
+    TCGv mask_cc;
+    TCGv shift;
     TCGv val;
-    TCGv val1, val2;
     TCGv src;
-    int offset;
-    int width;
-    int op;
+    TCGv offset;
+    TCGv width;
     TCGv reg;
-    TCGv addr;
-    uint32_t mask;
+    TCGv tmp;
 
     op = (insn >> 8) & 7;
     ext = lduw_code(s->pc);
@@ -2652,59 +2614,76 @@ DISAS_INSN(bitfield_mem)
        gen_addr_fault(s);
        return;
     }
-    if ((ext & 0x820) == 0) {
-       /* constant offset and width */
-       offset = (ext >> 6) & 31;
-       width = (ext & 31);
-       if (width == 0)
-           width = 32;
-       reg = DREG(ext, 12);
-       mask = 0xffffffff << (32 - width);
-       addr = tcg_temp_new_i32();
-       if (offset > 7) {
-           tcg_gen_addi_i32(addr, src, offset >> 3);
-           offset &= 7;
-       } else
-           tcg_gen_mov_i32(addr, src);
-       if (offset > 0)
-           mask <<= 32 - offset;
-       gen_bitfield_load(s, addr, offset + width, &val1, &val2);
-       val = gen_bitfield_cc(s, offset, width, val1, val2);
-       switch (op) {
-       case 0: /* bftst */
-           break;
-       case 1: /* bfextu */
-           if (width < 32)
-               tcg_gen_shri_i32(reg, val, 32 - width);
-           else
-               tcg_gen_mov_i32(reg, val);
-           break;
-       case 3: /* bfexts */
-           if (width < 32)
-               tcg_gen_sari_i32(reg, val, 32 - width);
-           else
-               tcg_gen_mov_i32(reg, val);
-           break;
-       case 5: /* bfffo */
-           gen_helper_bfffo(val, val, tcg_const_i32(width));
-           tcg_gen_addi_i32(reg, val, offset);
-           break;
-       case 2: /* bfchg */
-       case 4: /* bfclr */
-       case 6: /* bfset */
-           gen_bitfield_op(offset, width, op, val1, val2);
-           gen_bitfield_store(s, addr, offset + width, val1, val2);
-           break;
-       case 7: /* bfins */
-           gen_bitfield_op(offset, width, 4, val1, val2);
-           gen_bitfield_ins(offset, width, reg, val1, val2);
-           gen_bitfield_store(s, addr, offset + width, val1, val2);
-           break;
-       }
-       return;
+
+    bitfield_param(ext, &offset, &width, &mask_cc);
+
+    /* adjust src and offset */
+
+    /* src += offset >> 3; */
+
+    tmp = tcg_temp_new_i32();
+    tcg_gen_shri_i32(tmp, offset, 3);
+    tcg_gen_add_i32(src, src, tmp);
+
+    /* offset &= 7; */
+
+    tcg_gen_andi_i32(offset, offset, 7);
+
+    /* load */
+
+    bitfield = tcg_temp_new_i64();
+    gen_helper_bitfield_load(bitfield, src, offset, width);
+
+    /* compute CC and move bitfield into a 32bit */
+
+    val = gen_bitfield_cc(s, offset, mask_cc, bitfield);
+
+    /* execute operation */
+
+    reg = DREG(ext, 12);
+    switch (op) {
+    case 0: /* bftst */
+        break;
+    case 1: /* bfextu */
+        shift = tcg_temp_new_i32();
+        tcg_gen_sub_i32(shift, tcg_const_i32(32), width);
+        tcg_gen_shr_i32(reg, val, shift);
+        break;
+    case 2: /* bfchg */
+        mask_bitfield = gen_bitfield_mask(offset, width);
+        tcg_gen_xor_i64(bitfield, bitfield, mask_bitfield);
+        gen_helper_bitfield_store(src, offset, width, bitfield);
+        break;
+    case 3: /* bfexts */
+        shift = tcg_temp_new_i32();
+        tcg_gen_sub_i32(shift, tcg_const_i32(32), width);
+        tcg_gen_sar_i32(reg, val, shift);
+        break;
+    case 4: /* bfclr */
+        mask_bitfield = gen_bitfield_mask(offset, width);
+        tcg_gen_not_i64(mask_bitfield, mask_bitfield);
+        tcg_gen_and_i64(bitfield, bitfield, mask_bitfield);
+        gen_helper_bitfield_store(src, offset, width, bitfield);
+        break;
+    case 5: /* bfffo */
+        gen_helper_bfffo(val, val, width);
+        tcg_gen_add_i32(reg, val, offset);
+        break;
+    case 6: /* bfset */
+        mask_bitfield = gen_bitfield_mask(offset, width);
+        tcg_gen_or_i64(bitfield, bitfield, mask_bitfield);
+        gen_helper_bitfield_store(src, offset, width, bitfield);
+        break;
+    case 7: /* bfins */
+        /* clear */
+        mask_bitfield = gen_bitfield_mask(offset, width);
+        tcg_gen_not_i64(mask_bitfield, mask_bitfield);
+        tcg_gen_and_i64(bitfield, bitfield, mask_bitfield);
+        /* insert */
+        gen_bitfield_ins(offset, width, reg, bitfield);
+        gen_helper_bitfield_store(src, offset, width, bitfield);
+        break;
     }
-    /* Not yet implemented */
-    gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
 }
 
 DISAS_INSN(ff1)
-- 
1.7.2.3

  parent reply	other threads:[~2011-08-17 20:49 UTC|newest]

Thread overview: 125+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-17 20:46 [Qemu-devel] [RFC][PATCH 000/111] QEMU m68k core additions Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 001/111] linux-user: Signals processing is not thread-safe Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 002/111] linux-user: add qemu-wrapper Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 003/111] linux-user: define default cpu model in configure instead of linux-user/main.c Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 004/111] linux-user: specify the cpu model during configure Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 005/111] linux-user,m68k: display default cpu Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 006/111] linux-user: define new environment variables Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 007/111] linux-user: define a script to set binfmt using debian flavored tools Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 008/111] linux-user: define default cpu model in configure instead of linux-user/main.c Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 009/111] m68k: add tcg_gen_debug_insn_start() Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 010/111] m68k: define m680x0 CPUs and features Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 011/111] m68k: add missing accessing modes for some instructions Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 012/111] m68k: add Motorola 680x0 family common instructions Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 013/111] m68k: add Scc instruction with memory operand Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 014/111] m68k: add DBcc instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 015/111] m68k: modify movem instruction to manage word Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 016/111] m68k: add 64bit divide Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 017/111] m68k: add 32bit and 64bit multiply Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 018/111] m68k: add word data size for suba/adda Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 019/111] m68k: add fpu Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 020/111] m68k: add "byte", "word" and memory shift Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 021/111] m68k: add "byte", "word" and memory rotate Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 022/111] m68k: add bitfield_mem, bitfield_reg Bryce Lanham
2011-08-17 20:46 ` Bryce Lanham [this message]
2011-08-17 20:46 ` [Qemu-devel] [PATCH 024/111] m68k: add cas Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 025/111] " Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 026/111] m68k: define fcntl constants Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 027/111] m68k: add DBcc instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 028/111] m68k: allow fpu to manage double data type Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 029/111] m68k: allow fpu to manage double data type with fmove to <ea> Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 030/111] m68k: add FScc instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 031/111] m68k: add single data type to gen_ea Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 032/111] m68k: add linkl instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 033/111] m68k: Add fmovecr Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 034/111] m68k: correct typo on f64_to_i32() return type Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 035/111] m68k: improve CC_OP_LOGIC Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 036/111] m68k: correct neg condition code flags computation Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 037/111] Correct invalid use of "const void *" with "const uint8_t *" Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 038/111] m68k: add EA support for negx Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 039/111] m68k: add abcd instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 040/111] m68k: add sbcd instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 041/111] mm68k: add nbcd instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 042/111] m68k: set X flag according size of operand Set X flag correctly for addsub, arith_im, addsubq Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 043/111] m68k: on 0 bit shift, don't update X flag Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 044/111] m68k: improve addx instructions Add (byte, word) opsize Add memory access Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 045/111] m68k: improve subx, negx instructions Add (byte, word) opsize Add memory access (subx) Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 046/111] m68k: improve asl/asr evaluate correclty the missing V flag Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 047/111] m68k: use read_imm1() when it is possible Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 048/111] m68k: correct shift side effect for roxrl and roxll Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 049/111] m68k: asl/asr, clear C flag if shift count is 0 Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 050/111] m68k: lsl/lsr, " Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 051/111] m68k: correct divs.w and divu.w Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 052/111] m68k: correct flags with negl Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 053/111] m68k: for bitfield opcodes, correct operands corruption Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 054/111] m68k: Added ULL to 64 bit integer in helper.c Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 055/111] m68k: Correct bfclr in register case Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 056/111] m68k-linux-user: add '--enable-emulop' Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 057/111] m68k: correctly compute divsl Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 058/111] m68k: correctly compute divul Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 059/111] m68k: add m68030 definition Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 060/111] m68k: remove dead code Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 061/111] m68k: remove useless file m68k-qreg.h Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 062/111] m68k: FPU rework (draft) Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 063/111] m68k: some FPU debugging macros Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 064/111] m68k: more tests Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 065/111] m68k: correct compute gen_bitfield_cc() Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 066/111] m68k: add fgetexp Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 067/111] m68k: add fscale Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 068/111] m68k: correct addsubq Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 069/111] m68k: add fetox and flogn Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 070/111] m68k: initialize FRegs, define pickNaN() Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 071/111] m68k: correct cmpa comparison datatype Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 072/111] m68k: add flog10 Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 073/111] m68k: add cmpm instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 074/111] m68k: add ftwotox instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 075/111] m68k: better fpu traces Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 076/111] m68k: register source operand is always in extended size Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 077/111] m68k: add facos instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 078/111] m68k: add ftan instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 079/111] m68k: add fsin instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 080/111] m68k: add fcos instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 081/111] m68k: correct fpcr update Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 082/111] m68k: add fmod instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 083/111] m68k: flush flags before negx instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 084/111] m68k: correct fmovemx FP registers order Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 085/111] m68k: add fatan instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 086/111] m68k: correct bfins instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 087/111] m68k: fcmp correctly compares infinity Bryce Lanham
2011-08-17 22:35 ` [Qemu-devel] [RFC][PATCH 000/111] QEMU m68k core additions Anthony Liguori
2011-08-17 23:30   ` Bryce Lanham
2011-08-17 23:36     ` Peter Maydell
2011-08-18 16:05     ` Michael Roth
2011-08-18  7:02   ` Laurent Vivier
2011-08-18 11:12     ` François Revol
2011-08-18 14:02       ` Laurent Vivier
2011-08-18 19:42         ` Natalia Portillo
2011-08-18 19:57           ` Laurent Vivier
2011-08-18 20:13             ` Natalia Portillo
2011-08-18 20:51               ` Laurent Vivier
2011-08-19  2:14                 ` Natalia Portillo
2011-08-19  8:55                   ` François Revol
2011-08-19 15:52                     ` Natalia Portillo
2011-08-19 16:07                       ` Laurent Vivier
2011-08-19 20:08                         ` Anthony Liguori
2011-08-20 22:12                           ` Rob Landley
2011-08-20 22:12                     ` Rob Landley
2011-08-20 22:16                 ` Rob Landley
2011-08-20 21:06           ` Rob Landley
2011-08-20 20:57       ` Rob Landley
2011-08-20 21:16         ` Laurent Vivier
2011-08-20 22:28           ` Rob Landley
2011-08-20 22:39           ` Rob Landley
2011-08-20 23:24           ` Rob Landley
2011-08-20 20:55 ` Rob Landley
2011-08-20 23:17   ` Natalia Portillo
2011-08-20 23:42     ` Rob Landley
2011-08-21  0:23       ` Natalia Portillo
2011-08-21  0:50         ` Rob Landley
2011-08-21  2:02           ` Natalia Portillo
2011-08-21 22:14             ` Rob Landley
2011-08-22  2:15               ` Natalia Portillo
2011-08-23 12:30                 ` Rob Landley
2011-08-21 10:04       ` Laurent Vivier
2011-08-21 13:11         ` Natalia Portillo
2011-08-21 22:23         ` Rob Landley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1313614076-28878-24-git-send-email-blanham@gmail.com \
    --to=blanham@gmail.com \
    --cc=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.