diff mbox

[11/13] Add xxsel

Message ID 524EC1A7.7070304@gmail.com
State New
Headers show

Commit Message

Tom Musta Oct. 4, 2013, 1:24 p.m. UTC
This patch adds the VSX Select (xxsel) instruction.

The xxsel instruction has four VSR operands.  Thus the xC
instruction decoder is added.

The xxsel instruction is massively overloaded in the opcode
table since only bits 26 and 27 are opcode bits.  This
overloading is done in matrix fashion with two macros
(GEN_XXSEL_ROW and GEN_XX_SEL).

Signed-off-by: Tom Musta <tommusta@gmail.com>
---
  target-ppc/translate.c |   83 
++++++++++++++++++++++++++++++++++++++++++++++++
  1 files changed, 83 insertions(+), 0 deletions(-)

table                                                */
@@ -7327,6 +7328,42 @@ static void glue(gen_, name)(DisasContext * 
ctx)            \
  VSX_XXMRG(xxmrghw, 1)
  VSX_XXMRG(xxmrglw, 0)

+static void gen_xxsel(DisasContext * ctx)
+{
+    TCGv_i64 a, b, c;
+    if (unlikely(!ctx->vsx_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_VSXU);
+        return;
+    }
+    a = tcg_temp_new();
+    b = tcg_temp_new();
+    c = tcg_temp_new();
+
+    tcg_gen_mov_i64(a, cpu_vsrh(xA(ctx->opcode)));
+    tcg_gen_mov_i64(b, cpu_vsrh(xB(ctx->opcode)));
+    tcg_gen_mov_i64(c, cpu_vsrh(xC(ctx->opcode)));
+
+    tcg_gen_and_i64(b, b, c);
+    tcg_gen_not_i64(c, c);
+    tcg_gen_and_i64(a, a, c);
+    tcg_gen_or_i64(a, a, b);
+    tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), a);
+
+    tcg_gen_mov_i64(a, cpu_vsrl(xA(ctx->opcode)));
+    tcg_gen_mov_i64(b, cpu_vsrl(xB(ctx->opcode)));
+    tcg_gen_mov_i64(c, cpu_vsrl(xC(ctx->opcode)));
+
+    tcg_gen_and_i64(b, b, c);
+    tcg_gen_not_i64(c, c);
+    tcg_gen_and_i64(a, a, c);
+    tcg_gen_or_i64(a, a, b);
+    tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), a);
+
+    tcg_temp_free(a);
+    tcg_temp_free(b);
+    tcg_temp_free(c);
+}
+

  /***                           SPE 
extension                               ***/
  /* Register moves */
@@ -9843,6 +9880,52 @@ VSX_LOGICAL(xxlnor, 0x8, 0x14, PPC2_VSX),
  GEN_XX3FORM(xxmrghw, 0x08, 0x02, PPC2_VSX),
  GEN_XX3FORM(xxmrglw, 0x08, 0x06, PPC2_VSX),

+#define GEN_XXSEL_ROW(opc3) \
+GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x18, opc3, 0, PPC_NONE, PPC2_VSX), \
+GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x19, opc3, 0, PPC_NONE, PPC2_VSX), \
+GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1A, opc3, 0, PPC_NONE, PPC2_VSX), \
+GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1B, opc3, 0, PPC_NONE, PPC2_VSX), \
+GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1C, opc3, 0, PPC_NONE, PPC2_VSX), \
+GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1D, opc3, 0, PPC_NONE, PPC2_VSX), \
+GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1E, opc3, 0, PPC_NONE, PPC2_VSX), \
+GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1F, opc3, 0, PPC_NONE, PPC2_VSX), \
+
+#define GEN_XXSEL() \
+GEN_XXSEL_ROW(0x00) \
+GEN_XXSEL_ROW(0x01) \
+GEN_XXSEL_ROW(0x02) \
+GEN_XXSEL_ROW(0x03) \
+GEN_XXSEL_ROW(0x04) \
+GEN_XXSEL_ROW(0x05) \
+GEN_XXSEL_ROW(0x06) \
+GEN_XXSEL_ROW(0x07) \
+GEN_XXSEL_ROW(0x08) \
+GEN_XXSEL_ROW(0x09) \
+GEN_XXSEL_ROW(0x0A) \
+GEN_XXSEL_ROW(0x0B) \
+GEN_XXSEL_ROW(0x0C) \
+GEN_XXSEL_ROW(0x0D) \
+GEN_XXSEL_ROW(0x0E) \
+GEN_XXSEL_ROW(0x0F) \
+GEN_XXSEL_ROW(0x10) \
+GEN_XXSEL_ROW(0x11) \
+GEN_XXSEL_ROW(0x12) \
+GEN_XXSEL_ROW(0x13) \
+GEN_XXSEL_ROW(0x14) \
+GEN_XXSEL_ROW(0x15) \
+GEN_XXSEL_ROW(0x16) \
+GEN_XXSEL_ROW(0x17) \
+GEN_XXSEL_ROW(0x18) \
+GEN_XXSEL_ROW(0x19) \
+GEN_XXSEL_ROW(0x1A) \
+GEN_XXSEL_ROW(0x1B) \
+GEN_XXSEL_ROW(0x1C) \
+GEN_XXSEL_ROW(0x1D) \
+GEN_XXSEL_ROW(0x1E) \
+GEN_XXSEL_ROW(0x1F)
+
+GEN_XXSEL()
+
  GEN_XX3FORM_DM(xxpermdi, 0x08, 0x01),

  #undef GEN_SPE

Comments

Richard Henderson Oct. 9, 2013, 8:13 p.m. UTC | #1
On 10/04/2013 06:24 AM, Tom Musta wrote:
> +    tcg_gen_and_i64(b, b, c);
> +    tcg_gen_not_i64(c, c);
> +    tcg_gen_and_i64(a, a, c);

tcg_gen_andc_i64.

> +#define GEN_XXSEL() \
> +GEN_XXSEL_ROW(0x00) \
> +GEN_XXSEL_ROW(0x01) \

Why bother with defining GEN_XXSEL when its only used once?
Surely just put the rows there.

OTOH, this does suggest that we could do with a better way
to decode the instructions, because this is ugly...


r~
Tom Musta Oct. 10, 2013, 12:27 p.m. UTC | #2
On 10/9/2013 3:13 PM, Richard Henderson wrote:
> On 10/04/2013 06:24 AM, Tom Musta wrote:
>> +    tcg_gen_and_i64(b, b, c);
>> +    tcg_gen_not_i64(c, c);
>> +    tcg_gen_and_i64(a, a, c);
> tcg_gen_andc_i64.
>
>> +#define GEN_XXSEL() \
>> +GEN_XXSEL_ROW(0x00) \
>> +GEN_XXSEL_ROW(0x01) \
> Why bother with defining GEN_XXSEL when its only used once?
> Surely just put the rows there.
>
> OTOH, this does suggest that we could do with a better way
> to decode the instructions, because this is ugly...
>
>
> r~
Yeah ... it isn't very pretty.  There was precedent for this (see, for 
example, rldcl).  And the decoding logic very much wants to use 
instruction bits 26:30 and 21:25 as opc2 and opc3 respectively. Perhaps 
I could inject a handler for opcode 60 that would handle the VSX map a 
little more gracefully.

Is your concern aesthetic?  Memory consumption?  And do you feel this is 
a showstopper or something that could be addressed later?
Richard Henderson Oct. 10, 2013, 1:45 p.m. UTC | #3
On 10/10/2013 05:27 AM, Tom Musta wrote:
> Is your concern aesthetic?  Memory consumption?  And do you feel this is a
> showstopper or something that could be addressed later?

Aesthetic, and it definitely ought to be addressed outside this patch set.


r~
diff mbox

Patch

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index bd62c62..a29db98 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -501,6 +501,7 @@  EXTRACT_HELPER_SPLIT(xT, 0, 1, 21, 5);
  EXTRACT_HELPER_SPLIT(xS, 0, 1, 21, 5);
  EXTRACT_HELPER_SPLIT(xA, 2, 1, 16, 5);
  EXTRACT_HELPER_SPLIT(xB, 1, 1, 11, 5);
+EXTRACT_HELPER_SPLIT(xC, 3, 1,  6, 5);
  EXTRACT_HELPER(DM, 8, 2);
  /*****************************************************************************/
  /* PowerPC instructions