* [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
* [Qemu-devel] [PATCH 00/13] Alpha emulation improvements, round two
@ 2009-12-12 1:13 Richard Henderson
2009-12-10 20:04 ` [Qemu-devel] [PATCH 01/13] alpha: Implement missing MVI instructions Richard Henderson
` (12 more replies)
0 siblings, 13 replies; 14+ messages in thread
From: Richard Henderson @ 2009-12-12 1:13 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2581 bytes --]
There are two -d flags fixes herein, which helps with the rest.
Otherwise the improvements are in 3 categories:
(1) Implement the rd/wrunique PALcall in the translator, at least for
usermode. There's no reason to break the TB for a register move.
(2) Implement the byte manipulation instructions inline instead of
via helpers. Worst case these expand to about 6 tcg ops. I was
hoping without looking that tcg would do some simple CSE operations
within the block. Of course, cse isn't implemented yet, but there's
no reason that couldn't happen in the future.
A good test case for the cse might be
gcc.c-torture/execute/20040709-2.c, function retmeE:
120001964: 0f 00 50 2c ldq_u t1,15(a0)
120001968: 00 00 30 2c ldq_u t0,0(a0)
12000196c: e4 0e 50 4a insqh a2,a0,t3
120001970: 72 07 50 4a insql a2,a0,a2
120001974: e3 0e 30 4a insqh a1,a0,t2
120001978: 71 07 30 4a insql a1,a0,a1
12000197c: 03 04 72 44 or t2,a2,t2
120001980: 42 0e 50 48 mskqh t1,a0,t1
120001984: 41 06 30 48 mskql t0,a0,t0
120001988: 02 04 44 44 or t1,t3,t1
12000198c: 01 04 31 44 or t0,a1,t0
120001990: 0f 00 50 3c stq_u t1,15(a0)
120001994: 08 00 70 3c stq_u t2,8(a0)
120001998: 00 00 30 3c stq_u t0,0(a0)
Here we've got 6 byte manipulation insns using A0 as an input,
all of which compute at least (A0 & 7) * 8; there's even more
that could be shared in this block.
(3) There are three FP correctness fixes.
Not surprisingly from the last, there are now fewer gcc testsuite
failures. I suspect that I'll have to tackle the missing rounding
mode bits before the rest of the testsuite will work.
r~
Richard Henderson (13):
alpha: Implement missing MVI instructions.
alpha: Fix -d in_asm
alpha: Expand zap/zapnot with immediate inline.
alpha: Rewrite gen_ext_[hl] in terms of zapnot.
alpha: Fix fbcond branch offset.
alpha: Implement RD/WRUNIQUE in the translator
alpha: Expand ins*l inline.
alpha: Expand msk*l inline.
alpha: Expand msk*h inline.
alpha: Expand ins*h inline.
alpha: Fix FMOV.
alpha: Fix double log_cpu_state.
alpha: Implement fp branch/cmov inline.
hw/alpha_palcode.c | 11 +-
target-alpha/helper.h | 35 +--
target-alpha/op_helper.c | 228 ++++++++++------
target-alpha/translate.c | 645 +++++++++++++++++++++++++++++++---------------
4 files changed, 600 insertions(+), 319 deletions(-)
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2009-12-12 1:23 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [Qemu-devel] [PATCH 03/13] alpha: Expand zap/zapnot with immediate inline Richard Henderson
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 ` [Qemu-devel] [PATCH 05/13] alpha: Fix fbcond branch offset Richard Henderson
2009-12-11 17:38 ` [Qemu-devel] [PATCH 06/13] alpha: Implement RD/WRUNIQUE in the translator Richard Henderson
2009-12-11 18:39 ` [Qemu-devel] [PATCH 07/13] alpha: Expand ins*l inline Richard Henderson
2009-12-11 19:51 ` [Qemu-devel] [PATCH 08/13] alpha: Expand msk*l inline Richard Henderson
2009-12-11 19:58 ` [Qemu-devel] [PATCH 09/13] alpha: Expand msk*h inline Richard Henderson
2009-12-11 21:21 ` [Qemu-devel] [PATCH 11/13] alpha: Fix FMOV Richard Henderson
2009-12-11 21:23 ` [Qemu-devel] [PATCH 12/13] alpha: Fix double log_cpu_state 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
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.