Patchwork [11/13] Add xxsel

login
register
mail settings
Submitter Tom Musta
Date Oct. 4, 2013, 1:24 p.m.
Message ID <524EC1A7.7070304@gmail.com>
Download mbox | patch
Permalink /patch/280619/
State New
Headers show

Comments

Tom Musta - Oct. 4, 2013, 1:24 p.m.
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
Richard Henderson - Oct. 9, 2013, 8:13 p.m.
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.
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.
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~

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