* [Qemu-devel] [PATCH 01/13] alpha: Implement missing MVI instructions.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
@ 2009-12-10 20:04 ` Richard Henderson
2009-12-10 20:54 ` [Qemu-devel] [PATCH 02/13] alpha: Fix -d in_asm Richard Henderson
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-10 20:04 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 291 bytes --]
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/helper.h | 14 ++++
target-alpha/op_helper.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++
target-alpha/translate.c | 79 +++++++++++++--------
3 files changed, 231 insertions(+), 30 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-alpha-Implement-missing-MVI-instructions.patch --]
[-- Type: text/x-patch; name="0001-alpha-Implement-missing-MVI-instructions.patch", Size: 10817 bytes --]
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 9c60be1..850ba0d 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -36,6 +36,20 @@ DEF_HELPER_2(insqh, i64, i64, i64)
DEF_HELPER_2(cmpbge, i64, i64, i64)
+DEF_HELPER_2(minub8, i64, i64, i64)
+DEF_HELPER_2(minsb8, i64, i64, i64)
+DEF_HELPER_2(minuw4, i64, i64, i64)
+DEF_HELPER_2(minsw4, i64, i64, i64)
+DEF_HELPER_2(maxub8, i64, i64, i64)
+DEF_HELPER_2(maxsb8, i64, i64, i64)
+DEF_HELPER_2(maxuw4, i64, i64, i64)
+DEF_HELPER_2(maxsw4, i64, i64, i64)
+DEF_HELPER_2(perr, i64, i64, i64)
+DEF_HELPER_1(pklb, i64, i64)
+DEF_HELPER_1(pkwb, i64, i64)
+DEF_HELPER_1(unpkbl, i64, i64)
+DEF_HELPER_1(unpkbw, i64, i64)
+
DEF_HELPER_0(load_fpcr, i64)
DEF_HELPER_1(store_fpcr, void, i64)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 999a8ab..08d5924 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -277,6 +277,174 @@ uint64_t helper_cmpbge (uint64_t op1, uint64_t op2)
return res;
}
+uint64_t helper_minub8 (uint64_t op1, uint64_t op2)
+{
+ uint64_t res = 0;
+ uint8_t opa, opb, opr;
+ int i;
+
+ for (i = 0; i < 8; ++i) {
+ opa = op1 >> (i * 8);
+ opb = op2 >> (i * 8);
+ opr = opa < opb ? opa : opb;
+ res |= (uint64_t)opr << (i * 8);
+ }
+ return res;
+}
+
+uint64_t helper_minsb8 (uint64_t op1, uint64_t op2)
+{
+ uint64_t res = 0;
+ int8_t opa, opb;
+ uint8_t opr;
+ int i;
+
+ for (i = 0; i < 8; ++i) {
+ opa = op1 >> (i * 8);
+ opb = op2 >> (i * 8);
+ opr = opa < opb ? opa : opb;
+ res |= (uint64_t)opr << (i * 8);
+ }
+ return res;
+}
+
+uint64_t helper_minuw4 (uint64_t op1, uint64_t op2)
+{
+ uint64_t res = 0;
+ uint16_t opa, opb, opr;
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ opa = op1 >> (i * 16);
+ opb = op2 >> (i * 16);
+ opr = opa < opb ? opa : opb;
+ res |= (uint64_t)opr << (i * 16);
+ }
+ return res;
+}
+
+uint64_t helper_minsw4 (uint64_t op1, uint64_t op2)
+{
+ uint64_t res = 0;
+ int16_t opa, opb;
+ uint16_t opr;
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ opa = op1 >> (i * 16);
+ opb = op2 >> (i * 16);
+ opr = opa < opb ? opa : opb;
+ res |= (uint64_t)opr << (i * 16);
+ }
+ return res;
+}
+
+uint64_t helper_maxub8 (uint64_t op1, uint64_t op2)
+{
+ uint64_t res = 0;
+ uint8_t opa, opb, opr;
+ int i;
+
+ for (i = 0; i < 8; ++i) {
+ opa = op1 >> (i * 8);
+ opb = op2 >> (i * 8);
+ opr = opa > opb ? opa : opb;
+ res |= (uint64_t)opr << (i * 8);
+ }
+ return res;
+}
+
+uint64_t helper_maxsb8 (uint64_t op1, uint64_t op2)
+{
+ uint64_t res = 0;
+ int8_t opa, opb;
+ uint8_t opr;
+ int i;
+
+ for (i = 0; i < 8; ++i) {
+ opa = op1 >> (i * 8);
+ opb = op2 >> (i * 8);
+ opr = opa > opb ? opa : opb;
+ res |= (uint64_t)opr << (i * 8);
+ }
+ return res;
+}
+
+uint64_t helper_maxuw4 (uint64_t op1, uint64_t op2)
+{
+ uint64_t res = 0;
+ uint16_t opa, opb, opr;
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ opa = op1 >> (i * 16);
+ opb = op2 >> (i * 16);
+ opr = opa > opb ? opa : opb;
+ res |= (uint64_t)opr << (i * 16);
+ }
+ return res;
+}
+
+uint64_t helper_maxsw4 (uint64_t op1, uint64_t op2)
+{
+ uint64_t res = 0;
+ int16_t opa, opb;
+ uint16_t opr;
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ opa = op1 >> (i * 16);
+ opb = op2 >> (i * 16);
+ opr = opa > opb ? opa : opb;
+ res |= (uint64_t)opr << (i * 16);
+ }
+ return res;
+}
+
+uint64_t helper_perr (uint64_t op1, uint64_t op2)
+{
+ uint64_t res = 0;
+ uint8_t opa, opb, opr;
+ int i;
+
+ for (i = 0; i < 8; ++i) {
+ opa = op1 >> (i * 8);
+ opb = op2 >> (i * 8);
+ if (opa >= opb)
+ opr = opa - opb;
+ else
+ opr = opb - opa;
+ res += opr;
+ }
+ return res;
+}
+
+uint64_t helper_pklb (uint64_t op1)
+{
+ return (op1 & 0xff) | ((op1 >> 24) & 0xff00);
+}
+
+uint64_t helper_pkwb (uint64_t op1)
+{
+ return ((op1 & 0xff)
+ | ((op1 >> 8) & 0xff00)
+ | ((op1 >> 16) & 0xff0000)
+ | ((op1 >> 24) & 0xff000000));
+}
+
+uint64_t helper_unpkbl (uint64_t op1)
+{
+ return (op1 & 0xff) | ((op1 & 0xff00) << 24);
+}
+
+uint64_t helper_unpkbw (uint64_t op1)
+{
+ return ((op1 & 0xff)
+ | ((op1 & 0xff00) << 8)
+ | ((op1 & 0xff0000) << 16)
+ | ((op1 & 0xff000000) << 24));
+}
+
/* Floating point helpers */
/* F floating (VAX) */
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 3f8d1b2..851eb50 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -611,6 +611,30 @@ ARITH3(insqh)
ARITH3(umulh)
ARITH3(mullv)
ARITH3(mulqv)
+ARITH3(minub8)
+ARITH3(minsb8)
+ARITH3(minuw4)
+ARITH3(minsw4)
+ARITH3(maxub8)
+ARITH3(maxsb8)
+ARITH3(maxuw4)
+ARITH3(maxsw4)
+ARITH3(perr)
+
+#define MVIOP2(name) \
+static inline void glue(gen_, name)(int rb, int rc) \
+{ \
+ if (unlikely(rc == 31)) \
+ return; \
+ if (unlikely(rb == 31)) \
+ tcg_gen_movi_i64(cpu_ir[rc], 0); \
+ else \
+ gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]); \
+}
+MVIOP2(pklb)
+MVIOP2(pkwb)
+MVIOP2(unpkbl)
+MVIOP2(unpkbw)
static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit,
uint8_t lit)
@@ -619,7 +643,7 @@ static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit,
TCGv tmp;
if (unlikely(rc == 31))
- return;
+ return;
l1 = gen_new_label();
l2 = gen_new_label();
@@ -646,7 +670,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
uint32_t palcode;
int32_t disp21, disp16, disp12;
uint16_t fn11, fn16;
- uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
+ uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit, real_islit;
uint8_t lit;
int ret;
@@ -656,7 +680,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
rb = (insn >> 16) & 0x1F;
rc = insn & 0x1F;
sbz = (insn >> 13) & 0x07;
- islit = (insn >> 12) & 1;
+ real_islit = islit = (insn >> 12) & 1;
if (rb == 31 && !islit) {
islit = 1;
lit = 0;
@@ -1913,8 +1937,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
/* PERR */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ gen_perr(ra, rb, rc, islit, lit);
break;
case 0x32:
/* CTLZ */
@@ -1942,85 +1965,81 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
/* UNPKBW */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ if (real_islit || ra != 31)
+ goto invalid_opc;
+ gen_unpkbw (rb, rc);
break;
case 0x35:
- /* UNPKWL */
+ /* UNPKBL */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ if (real_islit || ra != 31)
+ goto invalid_opc;
+ gen_unpkbl (rb, rc);
break;
case 0x36:
/* PKWB */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ if (real_islit || ra != 31)
+ goto invalid_opc;
+ gen_pkwb (rb, rc);
break;
case 0x37:
/* PKLB */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ if (real_islit || ra != 31)
+ goto invalid_opc;
+ gen_pklb (rb, rc);
break;
case 0x38:
/* MINSB8 */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ gen_minsb8 (ra, rb, rc, islit, lit);
break;
case 0x39:
/* MINSW4 */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ gen_minsw4 (ra, rb, rc, islit, lit);
break;
case 0x3A:
/* MINUB8 */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ gen_minub8 (ra, rb, rc, islit, lit);
break;
case 0x3B:
/* MINUW4 */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ gen_minuw4 (ra, rb, rc, islit, lit);
break;
case 0x3C:
/* MAXUB8 */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ gen_maxub8 (ra, rb, rc, islit, lit);
break;
case 0x3D:
/* MAXUW4 */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ gen_maxuw4 (ra, rb, rc, islit, lit);
break;
case 0x3E:
/* MAXSB8 */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ gen_maxsb8 (ra, rb, rc, islit, lit);
break;
case 0x3F:
/* MAXSW4 */
if (!(ctx->amask & AMASK_MVI))
goto invalid_opc;
- /* XXX: TODO */
- goto invalid_opc;
+ gen_maxsw4 (ra, rb, rc, islit, lit);
break;
case 0x70:
/* FTOIT */
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 02/13] alpha: Fix -d in_asm
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
2009-12-10 20:04 ` [Qemu-devel] [PATCH 01/13] alpha: Implement missing MVI instructions Richard Henderson
@ 2009-12-10 20:54 ` Richard Henderson
2009-12-10 21:43 ` [Qemu-devel] [PATCH 03/13] alpha: Expand zap/zapnot with immediate inline Richard Henderson
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-10 20:54 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 407 bytes --]
Generic disassembly was incorrectly keyed on ALPHA_DEBUG_DISAS
rather than the generic DEBUG_DISAS. Use qemu_log_mask for
additional LOG_DISAS output. Delete some random insn_count
logging noise from gen_intermediate_code_internal.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/translate.c | 19 ++++---------------
1 files changed, 4 insertions(+), 15 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0002-alpha-Fix-d-in_asm.patch --]
[-- Type: text/x-patch; name="0002-alpha-Fix-d-in_asm.patch", Size: 2217 bytes --]
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 851eb50..4f923bb 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -35,7 +35,7 @@
#undef ALPHA_DEBUG_DISAS
#ifdef ALPHA_DEBUG_DISAS
-# define LOG_DISAS(...) qemu_log(__VA_ARGS__)
+# define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
#else
# define LOG_DISAS(...) do { } while (0)
#endif
@@ -696,8 +696,9 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
fn7 = (insn >> 5) & 0x0000007F;
fn2 = (insn >> 5) & 0x00000003;
ret = 0;
- LOG_DISAS("opc %02x ra %d rb %d rc %d disp16 %04x\n",
+ LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
opc, ra, rb, rc, disp16);
+
switch (opc) {
case 0x00:
/* CALL_PAL */
@@ -2353,9 +2354,6 @@ static inline void gen_intermediate_code_internal(CPUState *env,
TranslationBlock *tb,
int search_pc)
{
-#if defined ALPHA_DEBUG_DISAS
- static int insn_count;
-#endif
DisasContext ctx, *ctxp = &ctx;
target_ulong pc_start;
uint32_t insn;
@@ -2405,16 +2403,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
}
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
gen_io_start();
-#if defined ALPHA_DEBUG_DISAS
- insn_count++;
- LOG_DISAS("pc " TARGET_FMT_lx " mem_idx %d\n",
- ctx.pc, ctx.mem_idx);
-#endif
insn = ldl_code(ctx.pc);
-#if defined ALPHA_DEBUG_DISAS
- insn_count++;
- LOG_DISAS("opcode %08x %d\n", insn, insn_count);
-#endif
num_insns++;
ctx.pc += 4;
ret = translate_one(ctxp, insn);
@@ -2459,7 +2448,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
tb->size = ctx.pc - pc_start;
tb->icount = num_insns;
}
-#if defined ALPHA_DEBUG_DISAS
+#ifdef DEBUG_DISAS
log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("IN: %s\n", lookup_symbol(pc_start));
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 03/13] alpha: Expand zap/zapnot with immediate inline.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
2009-12-10 20:04 ` [Qemu-devel] [PATCH 01/13] alpha: Implement missing MVI instructions Richard Henderson
2009-12-10 20:54 ` [Qemu-devel] [PATCH 02/13] alpha: Fix -d in_asm Richard Henderson
@ 2009-12-10 21:43 ` Richard Henderson
2009-12-10 22:00 ` [Qemu-devel] [PATCH 04/13] alpha: Rewrite gen_ext_[hl] in terms of zapnot Richard Henderson
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-10 21:43 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 331 bytes --]
The vast majority of zap instructions have an immediate operand,
since zapnot is the canonical method to zero-extend from u16 or u32.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/translate.c | 61 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 59 insertions(+), 2 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0003-alpha-Expand-zap-zapnot-with-immediate-inline.patch --]
[-- Type: text/x-patch; name="0003-alpha-Expand-zap-zapnot-with-immediate-inline.patch", Size: 2285 bytes --]
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 4f923bb..bd193da 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -507,6 +507,65 @@ FCMOV(cmpfge)
FCMOV(cmpfle)
FCMOV(cmpfgt)
+/* Implement zapnot with an immediate operand, which expands to some
+ form of immediate AND. This is a basic building block in the
+ definition of many of the other byte manipulation instructions. */
+static inline void gen_zapnoti(int ra, int rc, uint8_t lit)
+{
+ uint64_t mask;
+ int i;
+
+ switch (lit) {
+ case 0x00:
+ tcg_gen_movi_i64(cpu_ir[rc], 0);
+ break;
+ case 0x01:
+ tcg_gen_ext8u_i64(cpu_ir[rc], cpu_ir[ra]);
+ break;
+ case 0x03:
+ tcg_gen_ext16u_i64(cpu_ir[rc], cpu_ir[ra]);
+ break;
+ case 0x0f:
+ tcg_gen_ext32u_i64(cpu_ir[rc], cpu_ir[ra]);
+ break;
+ case 0xff:
+ tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+ break;
+ default:
+ for (mask = i = 0; i < 8; ++i) {
+ if ((lit >> i) & 1)
+ mask |= 0xffull << (i * 8);
+ }
+ tcg_gen_andi_i64 (cpu_ir[rc], cpu_ir[ra], mask);
+ break;
+ }
+}
+
+static inline void gen_zapnot(int ra, int rb, int rc, int islit, uint8_t lit)
+{
+ if (unlikely(rc == 31))
+ return;
+ else if (unlikely(ra == 31))
+ tcg_gen_movi_i64(cpu_ir[rc], 0);
+ else if (islit)
+ gen_zapnoti(ra, rc, lit);
+ else
+ gen_helper_zapnot (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+}
+
+static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
+{
+ if (unlikely(rc == 31))
+ return;
+ else if (unlikely(ra == 31))
+ tcg_gen_movi_i64(cpu_ir[rc], 0);
+ else if (islit)
+ gen_zapnoti(ra, rc, ~lit);
+ else
+ gen_helper_zap (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+}
+
+
/* EXTWH, EXTWH, EXTLH, EXTQH */
static inline void gen_ext_h(void(*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
int ra, int rb, int rc, int islit, uint8_t lit)
@@ -598,8 +657,6 @@ ARITH3(mskwl)
ARITH3(inswl)
ARITH3(mskll)
ARITH3(insll)
-ARITH3(zap)
-ARITH3(zapnot)
ARITH3(mskql)
ARITH3(insql)
ARITH3(mskwh)
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 04/13] alpha: Rewrite gen_ext_[hl] in terms of zapnot.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (2 preceding siblings ...)
2009-12-10 21:43 ` [Qemu-devel] [PATCH 03/13] alpha: Expand zap/zapnot with immediate inline Richard Henderson
@ 2009-12-10 22:00 ` Richard Henderson
2009-12-11 17:07 ` [Qemu-devel] [PATCH 05/13] alpha: Fix fbcond branch offset Richard Henderson
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-10 22:00 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 354 bytes --]
The architecture manual specifies the EXT instructions
in terms of the ZAPNOT operation; writing it that way in
the translator makes things a bit clearer.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/translate.c | 57 ++++++++++++++++++++-------------------------
1 files changed, 25 insertions(+), 32 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0004-alpha-Rewrite-gen_ext_-hl-in-terms-of-zapnot.patch --]
[-- Type: text/x-patch; name="0004-alpha-Rewrite-gen_ext_-hl-in-terms-of-zapnot.patch", Size: 5326 bytes --]
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index bd193da..5e139e6 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -567,46 +567,41 @@ static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
/* EXTWH, EXTWH, EXTLH, EXTQH */
-static inline void gen_ext_h(void(*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
- int ra, int rb, int rc, int islit, uint8_t lit)
+static inline void gen_ext_h(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
{
if (unlikely(rc == 31))
return;
-
- if (ra != 31) {
+ else if (unlikely(ra == 31))
+ tcg_gen_movi_i64(cpu_ir[rc], 0);
+ else {
if (islit) {
- if (lit != 0)
- tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 64 - ((lit & 7) * 8));
- else
- tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+ lit = (64 - (lit & 7) * 8) & 0x3f;
+ tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit);
} else {
- TCGv tmp1;
- tmp1 = tcg_temp_new();
-
+ TCGv tmp1 = tcg_temp_new();
tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
tcg_gen_shli_i64(tmp1, tmp1, 3);
tcg_gen_neg_i64(tmp1, tmp1);
tcg_gen_andi_i64(tmp1, tmp1, 0x3f);
tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
-
tcg_temp_free(tmp1);
}
- if (tcg_gen_ext_i64)
- tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
- } else
- tcg_gen_movi_i64(cpu_ir[rc], 0);
+ gen_zapnoti(rc, rc, byte_mask);
+ }
}
/* EXTBL, EXTWL, EXTWL, EXTLL, EXTQL */
-static inline void gen_ext_l(void(*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
- int ra, int rb, int rc, int islit, uint8_t lit)
+static inline void gen_ext_l(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
{
if (unlikely(rc == 31))
return;
-
- if (ra != 31) {
+ else if (unlikely(ra == 31))
+ tcg_gen_movi_i64(cpu_ir[rc], 0);
+ else {
if (islit) {
- tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
+ tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
} else {
TCGv tmp = tcg_temp_new();
tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
@@ -614,10 +609,8 @@ static inline void gen_ext_l(void(*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
tcg_temp_free(tmp);
}
- if (tcg_gen_ext_i64)
- tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
- } else
- tcg_gen_movi_i64(cpu_ir[rc], 0);
+ gen_zapnoti(rc, rc, byte_mask);
+ }
}
/* Code to call arith3 helpers */
@@ -1276,7 +1269,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x06:
/* EXTBL */
- gen_ext_l(&tcg_gen_ext8u_i64, ra, rb, rc, islit, lit);
+ gen_ext_l(ra, rb, rc, islit, lit, 0x01);
break;
case 0x0B:
/* INSBL */
@@ -1288,7 +1281,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x16:
/* EXTWL */
- gen_ext_l(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
+ gen_ext_l(ra, rb, rc, islit, lit, 0x03);
break;
case 0x1B:
/* INSWL */
@@ -1300,7 +1293,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x26:
/* EXTLL */
- gen_ext_l(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);
+ gen_ext_l(ra, rb, rc, islit, lit, 0x0f);
break;
case 0x2B:
/* INSLL */
@@ -1336,7 +1329,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x36:
/* EXTQL */
- gen_ext_l(NULL, ra, rb, rc, islit, lit);
+ gen_ext_l(ra, rb, rc, islit, lit, 0xff);
break;
case 0x39:
/* SLL */
@@ -1384,7 +1377,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x5A:
/* EXTWH */
- gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
+ gen_ext_h(ra, rb, rc, islit, lit, 0x03);
break;
case 0x62:
/* MSKLH */
@@ -1396,7 +1389,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x6A:
/* EXTLH */
- gen_ext_h(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);
+ gen_ext_h(ra, rb, rc, islit, lit, 0x0f);
break;
case 0x72:
/* MSKQH */
@@ -1408,7 +1401,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x7A:
/* EXTQH */
- gen_ext_h(NULL, ra, rb, rc, islit, lit);
+ gen_ext_h(ra, rb, rc, islit, lit, 0xff);
break;
default:
goto invalid_opc;
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 05/13] alpha: Fix fbcond branch offset.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (3 preceding siblings ...)
2009-12-10 22:00 ` [Qemu-devel] [PATCH 04/13] alpha: Rewrite gen_ext_[hl] in terms of zapnot Richard Henderson
@ 2009-12-11 17:07 ` Richard Henderson
2009-12-11 17:38 ` [Qemu-devel] [PATCH 06/13] alpha: Implement RD/WRUNIQUE in the translator Richard Henderson
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-11 17:07 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 257 bytes --]
The instructions use a disp21 like all other branch insns,
not the disp16 that was being passed.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/translate.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0005-alpha-Fix-fbcond-branch-offset.patch --]
[-- Type: text/x-patch; name="0005-alpha-Fix-fbcond-branch-offset.patch", Size: 1485 bytes --]
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 5e139e6..cabf75a 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -314,8 +314,7 @@ static inline void gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
gen_set_label(l2);
}
-static inline void gen_fbcond(DisasContext *ctx, int opc, int ra,
- int32_t disp16)
+static inline void gen_fbcond(DisasContext *ctx, int opc, int ra, int32_t disp)
{
int l1, l2;
TCGv tmp;
@@ -356,7 +355,7 @@ static inline void gen_fbcond(DisasContext *ctx, int opc, int ra,
tcg_gen_movi_i64(cpu_pc, ctx->pc);
tcg_gen_br(l2);
gen_set_label(l1);
- tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));
+ tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
gen_set_label(l2);
}
@@ -2335,7 +2334,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
case 0x31: /* FBEQ */
case 0x32: /* FBLT */
case 0x33: /* FBLE */
- gen_fbcond(ctx, opc, ra, disp16);
+ gen_fbcond(ctx, opc, ra, disp21);
ret = 1;
break;
case 0x34:
@@ -2348,7 +2347,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
case 0x35: /* FBNE */
case 0x36: /* FBGE */
case 0x37: /* FBGT */
- gen_fbcond(ctx, opc, ra, disp16);
+ gen_fbcond(ctx, opc, ra, disp21);
ret = 1;
break;
case 0x38:
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 06/13] alpha: Implement RD/WRUNIQUE in the translator
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (4 preceding siblings ...)
2009-12-11 17:07 ` [Qemu-devel] [PATCH 05/13] alpha: Fix fbcond branch offset Richard Henderson
@ 2009-12-11 17:38 ` Richard Henderson
2009-12-11 18:39 ` [Qemu-devel] [PATCH 07/13] alpha: Expand ins*l inline Richard Henderson
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-11 17:38 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 398 bytes --]
When emulating user-mode only, there's no reason to exit
the translation block to effect a call_pal. We can generate
a move to/from the unique slot directly.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
hw/alpha_palcode.c | 11 +++++------
target-alpha/translate.c | 39 +++++++++++++++++++++++++++++----------
2 files changed, 34 insertions(+), 16 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0006-alpha-Implement-RD-WRUNIQUE-in-the-translator.patch --]
[-- Type: text/x-patch; name="0006-alpha-Implement-RD-WRUNIQUE-in-the-translator.patch", Size: 3367 bytes --]
diff --git a/hw/alpha_palcode.c b/hw/alpha_palcode.c
index 44b2ca4..4cc37fe 100644
--- a/hw/alpha_palcode.c
+++ b/hw/alpha_palcode.c
@@ -1060,7 +1060,6 @@ void call_pal (CPUState *env, int palcode)
{
target_long ret;
- qemu_log("%s: palcode %02x\n", __func__, palcode);
switch (palcode) {
case 0x80:
/* BPT */
@@ -1093,14 +1092,14 @@ void call_pal (CPUState *env, int palcode)
break;
case 0x9E:
/* RDUNIQUE */
- env->ir[IR_V0] = env->unique;
qemu_log("RDUNIQUE: " TARGET_FMT_lx "\n", env->unique);
- break;
+ /* Handled in the translator for usermode. */
+ abort ();
case 0x9F:
/* WRUNIQUE */
- env->unique = env->ir[IR_A0];
- qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->unique);
- break;
+ qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
+ /* Handled in the translator for usermode. */
+ abort ();
case 0xAA:
/* GENTRAP */
qemu_log("GENTRAP: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index cabf75a..b53737a 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -57,6 +57,9 @@ static TCGv cpu_ir[31];
static TCGv cpu_fir[31];
static TCGv cpu_pc;
static TCGv cpu_lock;
+#ifdef CONFIG_USER_ONLY
+static TCGv cpu_uniq;
+#endif
/* register names */
static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
@@ -93,6 +96,11 @@ static void alpha_translate_init(void)
cpu_lock = tcg_global_mem_new_i64(TCG_AREG0,
offsetof(CPUState, lock), "lock");
+#ifdef CONFIG_USER_ONLY
+ cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, unique), "uniq");
+#endif
+
/* register helpers */
#define GEN_HELPER 2
#include "helper.h"
@@ -751,23 +759,34 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
switch (opc) {
case 0x00:
/* CALL_PAL */
+#ifdef CONFIG_USER_ONLY
+ if (palcode == 0x9E) {
+ /* RDUNIQUE */
+ tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_uniq);
+ break;
+ } else if (palcode == 0x9F) {
+ /* WRUNIQUE */
+ tcg_gen_mov_i64(cpu_uniq, cpu_ir[IR_A0]);
+ break;
+ }
+#endif
if (palcode >= 0x80 && palcode < 0xC0) {
/* Unprivileged PAL call */
gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
-#if !defined (CONFIG_USER_ONLY)
- } else if (palcode < 0x40) {
+ ret = 3;
+ break;
+ }
+#ifndef CONFIG_USER_ONLY
+ if (palcode < 0x40) {
/* Privileged PAL code */
if (ctx->mem_idx & 1)
goto invalid_opc;
- else
- gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
-#endif
- } else {
- /* Invalid PAL call */
- goto invalid_opc;
+ gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
+ ret = 3;
}
- ret = 3;
- break;
+#endif
+ /* Invalid PAL call */
+ goto invalid_opc;
case 0x01:
/* OPC01 */
goto invalid_opc;
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 07/13] alpha: Expand ins*l inline.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (5 preceding siblings ...)
2009-12-11 17:38 ` [Qemu-devel] [PATCH 06/13] alpha: Implement RD/WRUNIQUE in the translator Richard Henderson
@ 2009-12-11 18:39 ` Richard Henderson
2009-12-11 19:51 ` [Qemu-devel] [PATCH 08/13] alpha: Expand msk*l inline Richard Henderson
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-11 18:39 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 333 bytes --]
Similar in difficulty to ext*l, already expanded.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/helper.h | 4 --
target-alpha/op_helper.c | 24 -------------
target-alpha/translate.c | 87 +++++++++++++++++++++++++++++++---------------
3 files changed, 59 insertions(+), 56 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0007-alpha-Expand-ins-l-inline.patch --]
[-- Type: text/x-patch; name="0007-alpha-Expand-ins-l-inline.patch", Size: 8305 bytes --]
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 850ba0d..8004aa1 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -18,15 +18,11 @@ DEF_HELPER_1(ctlz, i64, i64)
DEF_HELPER_1(cttz, i64, i64)
DEF_HELPER_2(mskbl, i64, i64, i64)
-DEF_HELPER_2(insbl, i64, i64, i64)
DEF_HELPER_2(mskwl, i64, i64, i64)
-DEF_HELPER_2(inswl, i64, i64, i64)
DEF_HELPER_2(mskll, i64, i64, i64)
-DEF_HELPER_2(insll, i64, i64, i64)
DEF_HELPER_2(zap, i64, i64, i64)
DEF_HELPER_2(zapnot, i64, i64, i64)
DEF_HELPER_2(mskql, i64, i64, i64)
-DEF_HELPER_2(insql, i64, i64, i64)
DEF_HELPER_2(mskwh, i64, i64, i64)
DEF_HELPER_2(inswh, i64, i64, i64)
DEF_HELPER_2(msklh, i64, i64, i64)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 08d5924..d2e43a5 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -180,34 +180,16 @@ uint64_t helper_mskbl(uint64_t val, uint64_t mask)
return byte_zap(val, 0x01 << (mask & 7));
}
-uint64_t helper_insbl(uint64_t val, uint64_t mask)
-{
- val <<= (mask & 7) * 8;
- return byte_zap(val, ~(0x01 << (mask & 7)));
-}
-
uint64_t helper_mskwl(uint64_t val, uint64_t mask)
{
return byte_zap(val, 0x03 << (mask & 7));
}
-uint64_t helper_inswl(uint64_t val, uint64_t mask)
-{
- val <<= (mask & 7) * 8;
- return byte_zap(val, ~(0x03 << (mask & 7)));
-}
-
uint64_t helper_mskll(uint64_t val, uint64_t mask)
{
return byte_zap(val, 0x0F << (mask & 7));
}
-uint64_t helper_insll(uint64_t val, uint64_t mask)
-{
- val <<= (mask & 7) * 8;
- return byte_zap(val, ~(0x0F << (mask & 7)));
-}
-
uint64_t helper_zap(uint64_t val, uint64_t mask)
{
return byte_zap(val, mask);
@@ -223,12 +205,6 @@ uint64_t helper_mskql(uint64_t val, uint64_t mask)
return byte_zap(val, 0xFF << (mask & 7));
}
-uint64_t helper_insql(uint64_t val, uint64_t mask)
-{
- val <<= (mask & 7) * 8;
- return byte_zap(val, ~(0xFF << (mask & 7)));
-}
-
uint64_t helper_mskwh(uint64_t val, uint64_t mask)
{
return byte_zap(val, (0x03 << (mask & 7)) >> 8);
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index b53737a..631b31f 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -514,36 +514,41 @@ FCMOV(cmpfge)
FCMOV(cmpfle)
FCMOV(cmpfgt)
+static inline uint64_t zapnot_mask(uint8_t lit)
+{
+ uint64_t mask = 0;
+ int i;
+
+ for (i = 0; i < 8; ++i) {
+ if ((lit >> i) & 1)
+ mask |= 0xffull << (i * 8);
+ }
+ return mask;
+}
+
/* Implement zapnot with an immediate operand, which expands to some
form of immediate AND. This is a basic building block in the
definition of many of the other byte manipulation instructions. */
-static inline void gen_zapnoti(int ra, int rc, uint8_t lit)
+static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
{
- uint64_t mask;
- int i;
-
switch (lit) {
case 0x00:
- tcg_gen_movi_i64(cpu_ir[rc], 0);
+ tcg_gen_movi_i64(dest, 0);
break;
case 0x01:
- tcg_gen_ext8u_i64(cpu_ir[rc], cpu_ir[ra]);
+ tcg_gen_ext8u_i64(dest, src);
break;
case 0x03:
- tcg_gen_ext16u_i64(cpu_ir[rc], cpu_ir[ra]);
+ tcg_gen_ext16u_i64(dest, src);
break;
case 0x0f:
- tcg_gen_ext32u_i64(cpu_ir[rc], cpu_ir[ra]);
+ tcg_gen_ext32u_i64(dest, src);
break;
case 0xff:
- tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+ tcg_gen_mov_i64(dest, src);
break;
default:
- for (mask = i = 0; i < 8; ++i) {
- if ((lit >> i) & 1)
- mask |= 0xffull << (i * 8);
- }
- tcg_gen_andi_i64 (cpu_ir[rc], cpu_ir[ra], mask);
+ tcg_gen_andi_i64 (dest, src, zapnot_mask (lit));
break;
}
}
@@ -555,7 +560,7 @@ static inline void gen_zapnot(int ra, int rb, int rc, int islit, uint8_t lit)
else if (unlikely(ra == 31))
tcg_gen_movi_i64(cpu_ir[rc], 0);
else if (islit)
- gen_zapnoti(ra, rc, lit);
+ gen_zapnoti(cpu_ir[rc], cpu_ir[ra], lit);
else
gen_helper_zapnot (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
}
@@ -567,13 +572,13 @@ static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
else if (unlikely(ra == 31))
tcg_gen_movi_i64(cpu_ir[rc], 0);
else if (islit)
- gen_zapnoti(ra, rc, ~lit);
+ gen_zapnoti(cpu_ir[rc], cpu_ir[ra], ~lit);
else
gen_helper_zap (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
}
-/* EXTWH, EXTWH, EXTLH, EXTQH */
+/* EXTWH, EXTLH, EXTQH */
static inline void gen_ext_h(int ra, int rb, int rc, int islit,
uint8_t lit, uint8_t byte_mask)
{
@@ -594,11 +599,11 @@ static inline void gen_ext_h(int ra, int rb, int rc, int islit,
tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
tcg_temp_free(tmp1);
}
- gen_zapnoti(rc, rc, byte_mask);
+ gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
}
}
-/* EXTBL, EXTWL, EXTWL, EXTLL, EXTQL */
+/* EXTBL, EXTWL, EXTLL, EXTQL */
static inline void gen_ext_l(int ra, int rb, int rc, int islit,
uint8_t lit, uint8_t byte_mask)
{
@@ -616,7 +621,37 @@ static inline void gen_ext_l(int ra, int rb, int rc, int islit,
tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
tcg_temp_free(tmp);
}
- gen_zapnoti(rc, rc, byte_mask);
+ gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
+ }
+}
+
+/* INSBL, INSWL, INSLL, INSQL */
+static inline void gen_ins_l(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
+{
+ if (unlikely(rc == 31))
+ return;
+ else if (unlikely(ra == 31))
+ tcg_gen_movi_i64(cpu_ir[rc], 0);
+ else {
+ TCGv tmp = tcg_temp_new();
+
+ /* The instruction description has us left-shift the byte mask
+ the same number of byte slots as the data and apply the zap
+ at the end. This is equivalent to simply performing the zap
+ first and shifting afterward. */
+ gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
+
+ if (islit) {
+ tcg_gen_shli_i64(cpu_ir[rc], tmp, (lit & 7) * 8);
+ } else {
+ TCGv shift = tcg_temp_new();
+ tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
+ tcg_gen_shli_i64(shift, shift, 3);
+ tcg_gen_shl_i64(cpu_ir[rc], tmp, shift);
+ tcg_temp_free(shift);
+ }
+ tcg_temp_free(tmp);
}
}
@@ -652,13 +687,9 @@ ARITH3(sublv)
ARITH3(addqv)
ARITH3(subqv)
ARITH3(mskbl)
-ARITH3(insbl)
ARITH3(mskwl)
-ARITH3(inswl)
ARITH3(mskll)
-ARITH3(insll)
ARITH3(mskql)
-ARITH3(insql)
ARITH3(mskwh)
ARITH3(inswh)
ARITH3(msklh)
@@ -1291,7 +1322,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x0B:
/* INSBL */
- gen_insbl(ra, rb, rc, islit, lit);
+ gen_ins_l(ra, rb, rc, islit, lit, 0x01);
break;
case 0x12:
/* MSKWL */
@@ -1303,7 +1334,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x1B:
/* INSWL */
- gen_inswl(ra, rb, rc, islit, lit);
+ gen_ins_l(ra, rb, rc, islit, lit, 0x03);
break;
case 0x22:
/* MSKLL */
@@ -1315,7 +1346,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x2B:
/* INSLL */
- gen_insll(ra, rb, rc, islit, lit);
+ gen_ins_l(ra, rb, rc, islit, lit, 0x0f);
break;
case 0x30:
/* ZAP */
@@ -1367,7 +1398,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x3B:
/* INSQL */
- gen_insql(ra, rb, rc, islit, lit);
+ gen_ins_l(ra, rb, rc, islit, lit, 0xff);
break;
case 0x3C:
/* SRA */
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 08/13] alpha: Expand msk*l inline.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (6 preceding siblings ...)
2009-12-11 18:39 ` [Qemu-devel] [PATCH 07/13] alpha: Expand ins*l inline Richard Henderson
@ 2009-12-11 19:51 ` Richard Henderson
2009-12-11 19:58 ` [Qemu-devel] [PATCH 09/13] alpha: Expand msk*h inline Richard Henderson
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-11 19:51 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 334 bytes --]
Similar in difficulty to ext*l, already expanded.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/helper.h | 4 ----
target-alpha/op_helper.c | 20 --------------------
target-alpha/translate.c | 38 ++++++++++++++++++++++++++++++--------
3 files changed, 30 insertions(+), 32 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0008-alpha-Expand-msk-l-inline.patch --]
[-- Type: text/x-patch; name="0008-alpha-Expand-msk-l-inline.patch", Size: 4425 bytes --]
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 8004aa1..8db73b0 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -17,12 +17,8 @@ DEF_HELPER_1(ctpop, i64, i64)
DEF_HELPER_1(ctlz, i64, i64)
DEF_HELPER_1(cttz, i64, i64)
-DEF_HELPER_2(mskbl, i64, i64, i64)
-DEF_HELPER_2(mskwl, i64, i64, i64)
-DEF_HELPER_2(mskll, i64, i64, i64)
DEF_HELPER_2(zap, i64, i64, i64)
DEF_HELPER_2(zapnot, i64, i64, i64)
-DEF_HELPER_2(mskql, i64, i64, i64)
DEF_HELPER_2(mskwh, i64, i64, i64)
DEF_HELPER_2(inswh, i64, i64, i64)
DEF_HELPER_2(msklh, i64, i64, i64)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index d2e43a5..591adbd 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -175,21 +175,6 @@ static inline uint64_t byte_zap(uint64_t op, uint8_t mskb)
return op & ~mask;
}
-uint64_t helper_mskbl(uint64_t val, uint64_t mask)
-{
- return byte_zap(val, 0x01 << (mask & 7));
-}
-
-uint64_t helper_mskwl(uint64_t val, uint64_t mask)
-{
- return byte_zap(val, 0x03 << (mask & 7));
-}
-
-uint64_t helper_mskll(uint64_t val, uint64_t mask)
-{
- return byte_zap(val, 0x0F << (mask & 7));
-}
-
uint64_t helper_zap(uint64_t val, uint64_t mask)
{
return byte_zap(val, mask);
@@ -200,11 +185,6 @@ uint64_t helper_zapnot(uint64_t val, uint64_t mask)
return byte_zap(val, ~mask);
}
-uint64_t helper_mskql(uint64_t val, uint64_t mask)
-{
- return byte_zap(val, 0xFF << (mask & 7));
-}
-
uint64_t helper_mskwh(uint64_t val, uint64_t mask)
{
return byte_zap(val, (0x03 << (mask & 7)) >> 8);
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 631b31f..3e50d27 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -655,6 +655,32 @@ static inline void gen_ins_l(int ra, int rb, int rc, int islit,
}
}
+/* MSKBL, MSKWL, MSKLL, MSKQL */
+static inline void gen_msk_l(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
+{
+ if (unlikely(rc == 31))
+ return;
+ else if (unlikely(ra == 31))
+ tcg_gen_movi_i64(cpu_ir[rc], 0);
+ else if (islit) {
+ gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~(byte_mask << (lit & 7)));
+ } else {
+ TCGv shift = tcg_temp_new();
+ TCGv mask = tcg_temp_new();
+
+ tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
+ tcg_gen_shli_i64(shift, shift, 3);
+ tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
+ tcg_gen_shl_i64(mask, mask, shift);
+
+ tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
+
+ tcg_temp_free(mask);
+ tcg_temp_free(shift);
+ }
+}
+
/* Code to call arith3 helpers */
#define ARITH3(name) \
static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
@@ -686,10 +712,6 @@ ARITH3(addlv)
ARITH3(sublv)
ARITH3(addqv)
ARITH3(subqv)
-ARITH3(mskbl)
-ARITH3(mskwl)
-ARITH3(mskll)
-ARITH3(mskql)
ARITH3(mskwh)
ARITH3(inswh)
ARITH3(msklh)
@@ -1314,7 +1336,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
switch (fn7) {
case 0x02:
/* MSKBL */
- gen_mskbl(ra, rb, rc, islit, lit);
+ gen_msk_l(ra, rb, rc, islit, lit, 0x01);
break;
case 0x06:
/* EXTBL */
@@ -1326,7 +1348,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x12:
/* MSKWL */
- gen_mskwl(ra, rb, rc, islit, lit);
+ gen_msk_l(ra, rb, rc, islit, lit, 0x03);
break;
case 0x16:
/* EXTWL */
@@ -1338,7 +1360,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x22:
/* MSKLL */
- gen_mskll(ra, rb, rc, islit, lit);
+ gen_msk_l(ra, rb, rc, islit, lit, 0x0f);
break;
case 0x26:
/* EXTLL */
@@ -1358,7 +1380,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x32:
/* MSKQL */
- gen_mskql(ra, rb, rc, islit, lit);
+ gen_msk_l(ra, rb, rc, islit, lit, 0xff);
break;
case 0x34:
/* SRL */
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 09/13] alpha: Expand msk*h inline.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (7 preceding siblings ...)
2009-12-11 19:51 ` [Qemu-devel] [PATCH 08/13] alpha: Expand msk*l inline Richard Henderson
@ 2009-12-11 19:58 ` Richard Henderson
2009-12-11 21:21 ` [Qemu-devel] [PATCH 11/13] alpha: Fix FMOV Richard Henderson
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-11 19:58 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 277 bytes --]
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/helper.h | 3 --
target-alpha/op_helper.c | 15 -----------
target-alpha/translate.c | 63 +++++++++++++++++++++++++++++++++++----------
3 files changed, 49 insertions(+), 32 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0009-alpha-Expand-msk-h-inline.patch --]
[-- Type: text/x-patch; name="0009-alpha-Expand-msk-h-inline.patch", Size: 6172 bytes --]
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 8db73b0..a545c5c 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -19,11 +19,8 @@ DEF_HELPER_1(cttz, i64, i64)
DEF_HELPER_2(zap, i64, i64, i64)
DEF_HELPER_2(zapnot, i64, i64, i64)
-DEF_HELPER_2(mskwh, i64, i64, i64)
DEF_HELPER_2(inswh, i64, i64, i64)
-DEF_HELPER_2(msklh, i64, i64, i64)
DEF_HELPER_2(inslh, i64, i64, i64)
-DEF_HELPER_2(mskqh, i64, i64, i64)
DEF_HELPER_2(insqh, i64, i64, i64)
DEF_HELPER_2(cmpbge, i64, i64, i64)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 591adbd..b6ec0e8 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -185,33 +185,18 @@ uint64_t helper_zapnot(uint64_t val, uint64_t mask)
return byte_zap(val, ~mask);
}
-uint64_t helper_mskwh(uint64_t val, uint64_t mask)
-{
- return byte_zap(val, (0x03 << (mask & 7)) >> 8);
-}
-
uint64_t helper_inswh(uint64_t val, uint64_t mask)
{
val >>= 64 - ((mask & 7) * 8);
return byte_zap(val, ~((0x03 << (mask & 7)) >> 8));
}
-uint64_t helper_msklh(uint64_t val, uint64_t mask)
-{
- return byte_zap(val, (0x0F << (mask & 7)) >> 8);
-}
-
uint64_t helper_inslh(uint64_t val, uint64_t mask)
{
val >>= 64 - ((mask & 7) * 8);
return byte_zap(val, ~((0x0F << (mask & 7)) >> 8));
}
-uint64_t helper_mskqh(uint64_t val, uint64_t mask)
-{
- return byte_zap(val, (0xFF << (mask & 7)) >> 8);
-}
-
uint64_t helper_insqh(uint64_t val, uint64_t mask)
{
val >>= 64 - ((mask & 7) * 8);
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 3e50d27..92d001d 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -579,8 +579,8 @@ static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
/* EXTWH, EXTLH, EXTQH */
-static inline void gen_ext_h(int ra, int rb, int rc, int islit,
- uint8_t lit, uint8_t byte_mask)
+static void gen_ext_h(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
{
if (unlikely(rc == 31))
return;
@@ -604,8 +604,8 @@ static inline void gen_ext_h(int ra, int rb, int rc, int islit,
}
/* EXTBL, EXTWL, EXTLL, EXTQL */
-static inline void gen_ext_l(int ra, int rb, int rc, int islit,
- uint8_t lit, uint8_t byte_mask)
+static void gen_ext_l(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
{
if (unlikely(rc == 31))
return;
@@ -626,8 +626,8 @@ static inline void gen_ext_l(int ra, int rb, int rc, int islit,
}
/* INSBL, INSWL, INSLL, INSQL */
-static inline void gen_ins_l(int ra, int rb, int rc, int islit,
- uint8_t lit, uint8_t byte_mask)
+static void gen_ins_l(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
{
if (unlikely(rc == 31))
return;
@@ -655,9 +655,47 @@ static inline void gen_ins_l(int ra, int rb, int rc, int islit,
}
}
+/* MSKWH, MSKLH, MSKQH */
+static void gen_msk_h(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
+{
+ if (unlikely(rc == 31))
+ return;
+ else if (unlikely(ra == 31))
+ tcg_gen_movi_i64(cpu_ir[rc], 0);
+ else if (islit) {
+ gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~((byte_mask << (lit & 7)) >> 8));
+ } else {
+ TCGv shift = tcg_temp_new();
+ TCGv mask = tcg_temp_new();
+
+ /* The instruction description is as above, where the byte_mask
+ is shifted left, and then we extract bits <15:8>. This can be
+ emulated with a right-shift on the expanded byte mask. This
+ requires extra care because for an input <2:0> == 0 we need a
+ shift of 64 bits in order to generate a zero. This is done by
+ splitting the shift into two parts, the variable shift - 1
+ followed by a constant 1 shift. The code we expand below is
+ equivalent to ~((B & 7) * 8) & 63. */
+
+ tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
+ tcg_gen_shli_i64(shift, shift, 3);
+ tcg_gen_not_i64(shift, shift);
+ tcg_gen_andi_i64(shift, shift, 0x3f);
+ tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
+ tcg_gen_shr_i64(mask, mask, shift);
+ tcg_gen_shri_i64(mask, mask, 1);
+
+ tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
+
+ tcg_temp_free(mask);
+ tcg_temp_free(shift);
+ }
+}
+
/* MSKBL, MSKWL, MSKLL, MSKQL */
-static inline void gen_msk_l(int ra, int rb, int rc, int islit,
- uint8_t lit, uint8_t byte_mask)
+static void gen_msk_l(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
{
if (unlikely(rc == 31))
return;
@@ -712,11 +750,8 @@ ARITH3(addlv)
ARITH3(sublv)
ARITH3(addqv)
ARITH3(subqv)
-ARITH3(mskwh)
ARITH3(inswh)
-ARITH3(msklh)
ARITH3(inslh)
-ARITH3(mskqh)
ARITH3(insqh)
ARITH3(umulh)
ARITH3(mullv)
@@ -1440,7 +1475,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x52:
/* MSKWH */
- gen_mskwh(ra, rb, rc, islit, lit);
+ gen_msk_h(ra, rb, rc, islit, lit, 0x03);
break;
case 0x57:
/* INSWH */
@@ -1452,7 +1487,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x62:
/* MSKLH */
- gen_msklh(ra, rb, rc, islit, lit);
+ gen_msk_h(ra, rb, rc, islit, lit, 0x0f);
break;
case 0x67:
/* INSLH */
@@ -1464,7 +1499,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x72:
/* MSKQH */
- gen_mskqh(ra, rb, rc, islit, lit);
+ gen_msk_h(ra, rb, rc, islit, lit, 0xff);
break;
case 0x77:
/* INSQH */
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 11/13] alpha: Fix FMOV.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (8 preceding siblings ...)
2009-12-11 19:58 ` [Qemu-devel] [PATCH 09/13] alpha: Expand msk*h inline Richard Henderson
@ 2009-12-11 21:21 ` Richard Henderson
2009-12-11 21:23 ` [Qemu-devel] [PATCH 12/13] alpha: Fix double log_cpu_state Richard Henderson
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-11 21:21 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 205 bytes --]
Properly handle move from the zero register.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/translate.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0011-alpha-Fix-FMOV.patch --]
[-- Type: text/x-patch; name="0011-alpha-Fix-FMOV.patch", Size: 896 bytes --]
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index d361ffe..3773ab4 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1834,12 +1834,16 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x020:
if (likely(rc != 31)) {
- if (ra == rb)
+ if (ra == rb) {
/* FMOV */
- tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
- else
+ if (ra == 31)
+ tcg_gen_movi_i64(cpu_fir[rc], 0);
+ else
+ tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
+ } else {
/* CPYS */
gen_fcpys(ra, rb, rc);
+ }
}
break;
case 0x021:
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 12/13] alpha: Fix double log_cpu_state.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (9 preceding siblings ...)
2009-12-11 21:21 ` [Qemu-devel] [PATCH 11/13] alpha: Fix FMOV Richard Henderson
@ 2009-12-11 21:23 ` Richard Henderson
2009-12-11 23:07 ` [Qemu-devel] [PATCH 13/13] alpha: Implement fp branch/cmov inline Richard Henderson
2009-12-12 0:31 ` [Qemu-devel] [PATCH 10/13] alpha: Expand ins*h inline Richard Henderson
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-11 21:23 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 198 bytes --]
The proper logging is handled by generic code.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/translate.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0012-alpha-Fix-double-log_cpu_state.patch --]
[-- Type: text/x-patch; name="0012-alpha-Fix-double-log_cpu_state.patch", Size: 530 bytes --]
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 3773ab4..e426677 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2648,7 +2648,6 @@ static inline void gen_intermediate_code_internal(CPUState *env,
tb->icount = num_insns;
}
#ifdef DEBUG_DISAS
- log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("IN: %s\n", lookup_symbol(pc_start));
log_target_disas(pc_start, ctx.pc - pc_start, 1);
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 13/13] alpha: Implement fp branch/cmov inline.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (10 preceding siblings ...)
2009-12-11 21:23 ` [Qemu-devel] [PATCH 12/13] alpha: Fix double log_cpu_state Richard Henderson
@ 2009-12-11 23:07 ` Richard Henderson
2009-12-12 0:31 ` [Qemu-devel] [PATCH 10/13] alpha: Expand ins*h inline Richard Henderson
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-11 23:07 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 516 bytes --]
The old fcmov implementation had a typo:
- tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
which moved the condition, not the second source, to the destination.
But it's also easy to implement the simplified fp comparison inline.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/helper.h | 7 --
target-alpha/op_helper.c | 31 -------
target-alpha/translate.c | 197 ++++++++++++++++++++++++++--------------------
3 files changed, 110 insertions(+), 125 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0013-alpha-Implement-fp-branch-cmov-inline.patch --]
[-- Type: text/x-patch; name="0013-alpha-Implement-fp-branch-cmov-inline.patch", Size: 11654 bytes --]
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 4eb3b6f..bedd3c0 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -77,13 +77,6 @@ DEF_HELPER_2(cmpgeq, i64, i64, i64)
DEF_HELPER_2(cmpgle, i64, i64, i64)
DEF_HELPER_2(cmpglt, i64, i64, i64)
-DEF_HELPER_1(cmpfeq, i64, i64)
-DEF_HELPER_1(cmpfne, i64, i64)
-DEF_HELPER_1(cmpflt, i64, i64)
-DEF_HELPER_1(cmpfle, i64, i64)
-DEF_HELPER_1(cmpfgt, i64, i64)
-DEF_HELPER_1(cmpfge, i64, i64)
-
DEF_HELPER_2(cpys, i64, i64, i64)
DEF_HELPER_2(cpysn, i64, i64, i64)
DEF_HELPER_2(cpyse, i64, i64, i64)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index d7f4fb2..8eba5ec 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -884,37 +884,6 @@ uint64_t helper_cmpglt(uint64_t a, uint64_t b)
return 0;
}
-uint64_t helper_cmpfeq (uint64_t a)
-{
- return !(a & 0x7FFFFFFFFFFFFFFFULL);
-}
-
-uint64_t helper_cmpfne (uint64_t a)
-{
- return (a & 0x7FFFFFFFFFFFFFFFULL);
-}
-
-uint64_t helper_cmpflt (uint64_t a)
-{
- return (a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL);
-}
-
-uint64_t helper_cmpfle (uint64_t a)
-{
- return (a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL);
-}
-
-uint64_t helper_cmpfgt (uint64_t a)
-{
- return !(a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL);
-}
-
-uint64_t helper_cmpfge (uint64_t a)
-{
- return !(a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL);
-}
-
-
/* Floating point format conversion */
uint64_t helper_cvtts (uint64_t a)
{
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index e426677..5b34fc6 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -294,77 +294,98 @@ static inline void gen_store_mem(DisasContext *ctx,
tcg_temp_free(addr);
}
-static inline void gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
- int32_t disp, int mask)
+static void gen_bcond_pcload(DisasContext *ctx, int32_t disp, int lab_true)
{
- int l1, l2;
+ int lab_over = gen_new_label();
+
+ tcg_gen_movi_i64(cpu_pc, ctx->pc);
+ tcg_gen_br(lab_over);
+ gen_set_label(lab_true);
+ tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
+ gen_set_label(lab_over);
+}
+
+static void gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
+ int32_t disp, int mask)
+{
+ int lab_true = gen_new_label();
- l1 = gen_new_label();
- l2 = gen_new_label();
if (likely(ra != 31)) {
if (mask) {
TCGv tmp = tcg_temp_new();
tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
- tcg_gen_brcondi_i64(cond, tmp, 0, l1);
+ tcg_gen_brcondi_i64(cond, tmp, 0, lab_true);
tcg_temp_free(tmp);
- } else
- tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, l1);
+ } else {
+ tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, lab_true);
+ }
} else {
/* Very uncommon case - Do not bother to optimize. */
TCGv tmp = tcg_const_i64(0);
- tcg_gen_brcondi_i64(cond, tmp, 0, l1);
+ tcg_gen_brcondi_i64(cond, tmp, 0, lab_true);
tcg_temp_free(tmp);
}
- tcg_gen_movi_i64(cpu_pc, ctx->pc);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
- gen_set_label(l2);
+ gen_bcond_pcload(ctx, disp, lab_true);
}
-static inline void gen_fbcond(DisasContext *ctx, int opc, int ra, int32_t disp)
+/* Generate a forward TCG branch to LAB_TRUE if RA cmp 0.0.
+ This is complicated by the fact that -0.0 compares the same as +0.0. */
+
+static void gen_fbcond_internal(TCGCond cond, TCGv src, int lab_true)
{
- int l1, l2;
+ int lab_false = -1;
+ uint64_t mzero = 1ull << 63;
TCGv tmp;
- TCGv src;
-
- l1 = gen_new_label();
- l2 = gen_new_label();
- if (ra != 31) {
+
+ switch (cond) {
+ case TCG_COND_LE:
+ case TCG_COND_GT:
+ /* For <= or >, the -0.0 value directly compares the way we want. */
+ tcg_gen_brcondi_i64(cond, src, 0, lab_true);
+ break;
+
+ case TCG_COND_EQ:
+ case TCG_COND_NE:
+ /* For == or !=, we can simply mask off the sign bit and compare. */
+ /* ??? Assume that the temporary is reclaimed at the branch. */
tmp = tcg_temp_new();
- src = cpu_fir[ra];
- } else {
- tmp = tcg_const_i64(0);
- src = tmp;
- }
- switch (opc) {
- case 0x31: /* FBEQ */
- gen_helper_cmpfeq(tmp, src);
- break;
- case 0x32: /* FBLT */
- gen_helper_cmpflt(tmp, src);
- break;
- case 0x33: /* FBLE */
- gen_helper_cmpfle(tmp, src);
- break;
- case 0x35: /* FBNE */
- gen_helper_cmpfne(tmp, src);
+ tcg_gen_andi_i64(tmp, src, mzero - 1);
+ tcg_gen_brcondi_i64(cond, tmp, 0, lab_true);
break;
- case 0x36: /* FBGE */
- gen_helper_cmpfge(tmp, src);
+
+ case TCG_COND_GE:
+ /* For >=, emit two branches to the destination. */
+ tcg_gen_brcondi_i64(cond, src, 0, lab_true);
+ tcg_gen_brcondi_i64(TCG_COND_EQ, src, mzero, lab_true);
break;
- case 0x37: /* FBGT */
- gen_helper_cmpfgt(tmp, src);
+
+ case TCG_COND_LT:
+ /* For <, first filter out -0.0 to what will be the fallthru. */
+ lab_false = gen_new_label();
+ tcg_gen_brcondi_i64(TCG_COND_EQ, src, mzero, lab_false);
+ tcg_gen_brcondi_i64(cond, src, 0, lab_true);
+ gen_set_label(lab_false);
break;
+
default:
abort();
}
- tcg_gen_brcondi_i64(TCG_COND_NE, tmp, 0, l1);
- tcg_gen_movi_i64(cpu_pc, ctx->pc);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
- gen_set_label(l2);
+}
+
+static void gen_fbcond(DisasContext *ctx, TCGCond cond, int ra, int32_t disp)
+{
+ int lab_true;
+
+ if (unlikely(ra == 31)) {
+ /* Very uncommon case, but easier to optimize it to an integer
+ comparison than continuing with the floating point comparison. */
+ gen_bcond(ctx, cond, ra, disp, 0);
+ return;
+ }
+
+ lab_true = gen_new_label();
+ gen_fbcond_internal(cond, cpu_fir[ra], lab_true);
+ gen_bcond_pcload(ctx, disp, lab_true);
}
static inline void gen_cmov(TCGCond inv_cond, int ra, int rb, int rc,
@@ -399,6 +420,28 @@ static inline void gen_cmov(TCGCond inv_cond, int ra, int rb, int rc,
gen_set_label(l1);
}
+static void gen_fcmov(TCGCond inv_cond, int ra, int rb, int rc)
+{
+ TCGv va = cpu_fir[ra];
+ int l1;
+
+ if (unlikely(rc == 31))
+ return;
+ if (unlikely(ra == 31)) {
+ /* ??? Assume that the temporary is reclaimed at the branch. */
+ va = tcg_const_i64(0);
+ }
+
+ l1 = gen_new_label();
+ gen_fbcond_internal(inv_cond, va, l1);
+
+ if (rb != 31)
+ tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[rb]);
+ else
+ tcg_gen_movi_i64(cpu_fir[rc], 0);
+ gen_set_label(l1);
+}
+
#define FARITH2(name) \
static inline void glue(gen_f, name)(int rb, int rc) \
{ \
@@ -482,38 +525,6 @@ FARITH3(cpys)
FARITH3(cpysn)
FARITH3(cpyse)
-#define FCMOV(name) \
-static inline void glue(gen_f, name)(int ra, int rb, int rc) \
-{ \
- int l1; \
- TCGv tmp; \
- \
- if (unlikely(rc == 31)) \
- return; \
- \
- l1 = gen_new_label(); \
- tmp = tcg_temp_new(); \
- if (ra != 31) { \
- tmp = tcg_temp_new(); \
- gen_helper_ ## name (tmp, cpu_fir[ra]); \
- } else { \
- tmp = tcg_const_i64(0); \
- gen_helper_ ## name (tmp, tmp); \
- } \
- tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1); \
- if (rb != 31) \
- tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]); \
- else \
- tcg_gen_movi_i64(cpu_fir[rc], 0); \
- gen_set_label(l1); \
-}
-FCMOV(cmpfeq)
-FCMOV(cmpfne)
-FCMOV(cmpflt)
-FCMOV(cmpfge)
-FCMOV(cmpfle)
-FCMOV(cmpfgt)
-
static inline uint64_t zapnot_mask(uint8_t lit)
{
uint64_t mask = 0;
@@ -1871,27 +1882,27 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x02A:
/* FCMOVEQ */
- gen_fcmpfeq(ra, rb, rc);
+ gen_fcmov(TCG_COND_NE, ra, rb, rc);
break;
case 0x02B:
/* FCMOVNE */
- gen_fcmpfne(ra, rb, rc);
+ gen_fcmov(TCG_COND_EQ, ra, rb, rc);
break;
case 0x02C:
/* FCMOVLT */
- gen_fcmpflt(ra, rb, rc);
+ gen_fcmov(TCG_COND_GE, ra, rb, rc);
break;
case 0x02D:
/* FCMOVGE */
- gen_fcmpfge(ra, rb, rc);
+ gen_fcmov(TCG_COND_LT, ra, rb, rc);
break;
case 0x02E:
/* FCMOVLE */
- gen_fcmpfle(ra, rb, rc);
+ gen_fcmov(TCG_COND_GT, ra, rb, rc);
break;
case 0x02F:
/* FCMOVGT */
- gen_fcmpfgt(ra, rb, rc);
+ gen_fcmov(TCG_COND_LE, ra, rb, rc);
break;
case 0x030:
/* CVTQL */
@@ -2482,9 +2493,15 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
ret = 1;
break;
case 0x31: /* FBEQ */
+ gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
+ ret = 1;
+ break;
case 0x32: /* FBLT */
+ gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
+ ret = 1;
+ break;
case 0x33: /* FBLE */
- gen_fbcond(ctx, opc, ra, disp21);
+ gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
ret = 1;
break;
case 0x34:
@@ -2495,9 +2512,15 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
ret = 1;
break;
case 0x35: /* FBNE */
+ gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
+ ret = 1;
+ break;
case 0x36: /* FBGE */
+ gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
+ ret = 1;
+ break;
case 0x37: /* FBGT */
- gen_fbcond(ctx, opc, ra, disp21);
+ gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
ret = 1;
break;
case 0x38:
^ permalink raw reply related [flat|nested] 14+ messages in thread* [Qemu-devel] [PATCH 10/13] alpha: Expand ins*h inline.
2009-12-12 1:13 [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two Richard Henderson
` (11 preceding siblings ...)
2009-12-11 23:07 ` [Qemu-devel] [PATCH 13/13] alpha: Implement fp branch/cmov inline Richard Henderson
@ 2009-12-12 0:31 ` Richard Henderson
12 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-12 0:31 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 282 bytes --]
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/helper.h | 3 --
target-alpha/op_helper.c | 18 ----------------
target-alpha/translate.c | 51 ++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 45 insertions(+), 27 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0010-alpha-Expand-ins-h-inline.patch --]
[-- Type: text/x-patch; name="0010-alpha-Expand-ins-h-inline.patch", Size: 4475 bytes --]
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index a545c5c..4eb3b6f 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -19,9 +19,6 @@ DEF_HELPER_1(cttz, i64, i64)
DEF_HELPER_2(zap, i64, i64, i64)
DEF_HELPER_2(zapnot, i64, i64, i64)
-DEF_HELPER_2(inswh, i64, i64, i64)
-DEF_HELPER_2(inslh, i64, i64, i64)
-DEF_HELPER_2(insqh, i64, i64, i64)
DEF_HELPER_2(cmpbge, i64, i64, i64)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index b6ec0e8..d7f4fb2 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -185,24 +185,6 @@ uint64_t helper_zapnot(uint64_t val, uint64_t mask)
return byte_zap(val, ~mask);
}
-uint64_t helper_inswh(uint64_t val, uint64_t mask)
-{
- val >>= 64 - ((mask & 7) * 8);
- return byte_zap(val, ~((0x03 << (mask & 7)) >> 8));
-}
-
-uint64_t helper_inslh(uint64_t val, uint64_t mask)
-{
- val >>= 64 - ((mask & 7) * 8);
- return byte_zap(val, ~((0x0F << (mask & 7)) >> 8));
-}
-
-uint64_t helper_insqh(uint64_t val, uint64_t mask)
-{
- val >>= 64 - ((mask & 7) * 8);
- return byte_zap(val, ~((0xFF << (mask & 7)) >> 8));
-}
-
uint64_t helper_cmpbge (uint64_t op1, uint64_t op2)
{
uint8_t opa, opb, res;
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 92d001d..d361ffe 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -625,6 +625,48 @@ static void gen_ext_l(int ra, int rb, int rc, int islit,
}
}
+/* INSWH, INSLH, INSQH */
+static void gen_ins_h(int ra, int rb, int rc, int islit,
+ uint8_t lit, uint8_t byte_mask)
+{
+ if (unlikely(rc == 31))
+ return;
+ else if (unlikely(ra == 31) || (islit && (lit & 7) == 0))
+ tcg_gen_movi_i64(cpu_ir[rc], 0);
+ else {
+ TCGv tmp = tcg_temp_new();
+
+ /* The instruction description has us left-shift the byte mask
+ and extract bits <15:8> and apply that zap at the end. This
+ is equivalent to simply performing the zap first and shifting
+ afterward. */
+ gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
+
+ if (islit) {
+ /* Note that we have handled the lit==0 case above. */
+ tcg_gen_shri_i64 (cpu_ir[rc], tmp, 64 - (lit & 7) * 8);
+ } else {
+ TCGv shift = tcg_temp_new();
+
+ /* If (B & 7) == 0, we need to shift by 64 and leave a zero.
+ Do this portably by splitting the shift into two parts:
+ shift_count-1 and 1. Arrange for the -1 by using
+ ones-complement instead of twos-complement in the negation:
+ ~((B & 7) * 8) & 63. */
+
+ tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
+ tcg_gen_shli_i64(shift, shift, 3);
+ tcg_gen_not_i64(shift, shift);
+ tcg_gen_andi_i64(shift, shift, 0x3f);
+
+ tcg_gen_shr_i64(cpu_ir[rc], tmp, shift);
+ tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[rc], 1);
+ tcg_temp_free(shift);
+ }
+ tcg_temp_free(tmp);
+ }
+}
+
/* INSBL, INSWL, INSLL, INSQL */
static void gen_ins_l(int ra, int rb, int rc, int islit,
uint8_t lit, uint8_t byte_mask)
@@ -750,9 +792,6 @@ ARITH3(addlv)
ARITH3(sublv)
ARITH3(addqv)
ARITH3(subqv)
-ARITH3(inswh)
-ARITH3(inslh)
-ARITH3(insqh)
ARITH3(umulh)
ARITH3(mullv)
ARITH3(mulqv)
@@ -1479,7 +1518,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x57:
/* INSWH */
- gen_inswh(ra, rb, rc, islit, lit);
+ gen_ins_h(ra, rb, rc, islit, lit, 0x03);
break;
case 0x5A:
/* EXTWH */
@@ -1491,7 +1530,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x67:
/* INSLH */
- gen_inslh(ra, rb, rc, islit, lit);
+ gen_ins_h(ra, rb, rc, islit, lit, 0x0f);
break;
case 0x6A:
/* EXTLH */
@@ -1503,7 +1542,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
break;
case 0x77:
/* INSQH */
- gen_insqh(ra, rb, rc, islit, lit);
+ gen_ins_h(ra, rb, rc, islit, lit, 0xff);
break;
case 0x7A:
/* EXTQH */
^ permalink raw reply related [flat|nested] 14+ messages in thread