diff mbox series

[RFC,v20,4/8] target-avr: Add instruction decoding

Message ID 20190530190738.22713-5-mrolnik@gmail.com (mailing list archive)
State New, archived
Headers show
Series QEMU AVR 8 bit cores | expand

Commit Message

Michael Rolnik May 30, 2019, 7:07 p.m. UTC
This includes:
- encoding of all 16 bit instructions
- encoding of all 32 bit instructions

Signed-off-by: Michael Rolnik <mrolnik@gmail.com>
---
 target/avr/insn16.decode | 160 +++++++++++++++++++++++++++++++++++++++
 target/avr/insn32.decode |  10 +++
 2 files changed, 170 insertions(+)
 create mode 100644 target/avr/insn16.decode
 create mode 100644 target/avr/insn32.decode

Comments

Richard Henderson May 31, 2019, 2:45 p.m. UTC | #1
On 5/30/19 2:07 PM, Michael Rolnik wrote:
> This includes:
> - encoding of all 16 bit instructions
> - encoding of all 32 bit instructions
> 
> Signed-off-by: Michael Rolnik <mrolnik@gmail.com>
> ---
>  target/avr/insn16.decode | 160 +++++++++++++++++++++++++++++++++++++++
>  target/avr/insn32.decode |  10 +++
>  2 files changed, 170 insertions(+)
>  create mode 100644 target/avr/insn16.decode
>  create mode 100644 target/avr/insn32.decode

Two things:

(1) decodetree can handle variable-width ISA now.

It's slightly ugly in that the %field numbering is little-endian and thus
varies for each insn size.  But the in-flight patch set for target/rx shows
that it works.

That said, I don't think you need that because,

(2) The four instructions that are 32-bits do not have
    any opcode bits in the second 16-bits.

E.g.

# The 22-bit immediate is partially in the opcode word,
# and partially in the next.  Use append_16 to build the
# complete 22-bit value.
%imm_call	4:5 0:1			!function=append_16
CALL		1001 010. .... 111.	imm=%imm_call
JMP		1001 010. .... 110.	imm=%imm_call

# The 16-bit immediate is completely in the next word.
# Fields cannot be defined with no bits, so we cannot play
# the same trick and append to a zero-bit value.
# Defer reading the immediate until trans_{LDS,STS}.
@ldst_s		.... ... rd:5 ....	imm=0
LDS		1001 000 ..... 0000	@ldst_s
STS		1001 001 ..... 0000	@ldst_s


static uint16_t next_word(DisasContext *ctx)
{
    return cpu_lduw_code(ctx->env, ctx->npc++ * 2);
}

static int append_16(DisasContext *ctx, int x)
{
    return x << 16 | next_word(ctx);
}

static bool trans_LDS(DisasContext *ctx, arg_ldst_s *a)
{
    a->imm = next_word(ctx);
    // other stuff
}

I realize that next_word as written does not fit in to how you currently
process instructions in the loop, but I also think that's a mistake.  I'll
respond to that in its place in the next patch.

That said, next_word *could* be written to use ctx->inst[0].opcode.


r~
Michael Rolnik June 3, 2019, 8:13 p.m. UTC | #2
Richard,
I don't understand what I should do. Do you want me to merge decode files?

On Fri, May 31, 2019 at 5:45 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 5/30/19 2:07 PM, Michael Rolnik wrote:
> > This includes:
> > - encoding of all 16 bit instructions
> > - encoding of all 32 bit instructions
> >
> > Signed-off-by: Michael Rolnik <mrolnik@gmail.com>
> > ---
> >  target/avr/insn16.decode | 160 +++++++++++++++++++++++++++++++++++++++
> >  target/avr/insn32.decode |  10 +++
> >  2 files changed, 170 insertions(+)
> >  create mode 100644 target/avr/insn16.decode
> >  create mode 100644 target/avr/insn32.decode
>
> Two things:
>
> (1) decodetree can handle variable-width ISA now.
>
> It's slightly ugly in that the %field numbering is little-endian and thus
> varies for each insn size.  But the in-flight patch set for target/rx shows
> that it works.
>
> That said, I don't think you need that because,
>
> (2) The four instructions that are 32-bits do not have
>     any opcode bits in the second 16-bits.
>
> E.g.
>
> # The 22-bit immediate is partially in the opcode word,
> # and partially in the next.  Use append_16 to build the
> # complete 22-bit value.
> %imm_call       4:5 0:1                 !function=append_16
> CALL            1001 010. .... 111.     imm=%imm_call
> JMP             1001 010. .... 110.     imm=%imm_call
>
> # The 16-bit immediate is completely in the next word.
> # Fields cannot be defined with no bits, so we cannot play
> # the same trick and append to a zero-bit value.
> # Defer reading the immediate until trans_{LDS,STS}.
> @ldst_s         .... ... rd:5 ....      imm=0
> LDS             1001 000 ..... 0000     @ldst_s
> STS             1001 001 ..... 0000     @ldst_s
>
>
> static uint16_t next_word(DisasContext *ctx)
> {
>     return cpu_lduw_code(ctx->env, ctx->npc++ * 2);
> }
>
> static int append_16(DisasContext *ctx, int x)
> {
>     return x << 16 | next_word(ctx);
> }
>
> static bool trans_LDS(DisasContext *ctx, arg_ldst_s *a)
> {
>     a->imm = next_word(ctx);
>     // other stuff
> }
>
> I realize that next_word as written does not fit in to how you currently
> process instructions in the loop, but I also think that's a mistake.  I'll
> respond to that in its place in the next patch.
>
> That said, next_word *could* be written to use ctx->inst[0].opcode.
>
>
> r~
>
Richard Henderson June 3, 2019, 9:48 p.m. UTC | #3
On 6/3/19 3:13 PM, Michael Rolnik wrote:
> Richard,
> I don't understand what I should do. Do you want me to merge decode files?

Yes, using the mechanisms previously described.


r~

> 
> On Fri, May 31, 2019 at 5:45 PM Richard Henderson <richard.henderson@linaro.org
> <mailto:richard.henderson@linaro.org>> wrote:
> 
>     On 5/30/19 2:07 PM, Michael Rolnik wrote:
>     > This includes:
>     > - encoding of all 16 bit instructions
>     > - encoding of all 32 bit instructions
>     >
>     > Signed-off-by: Michael Rolnik <mrolnik@gmail.com <mailto:mrolnik@gmail.com>>
>     > ---
>     >  target/avr/insn16.decode | 160 +++++++++++++++++++++++++++++++++++++++
>     >  target/avr/insn32.decode |  10 +++
>     >  2 files changed, 170 insertions(+)
>     >  create mode 100644 target/avr/insn16.decode
>     >  create mode 100644 target/avr/insn32.decode
> 
>     Two things:
> 
>     (1) decodetree can handle variable-width ISA now.
> 
>     It's slightly ugly in that the %field numbering is little-endian and thus
>     varies for each insn size.  But the in-flight patch set for target/rx shows
>     that it works.
> 
>     That said, I don't think you need that because,
> 
>     (2) The four instructions that are 32-bits do not have
>         any opcode bits in the second 16-bits.
> 
>     E.g.
> 
>     # The 22-bit immediate is partially in the opcode word,
>     # and partially in the next.  Use append_16 to build the
>     # complete 22-bit value.
>     %imm_call       4:5 0:1                 !function=append_16
>     CALL            1001 010. .... 111.     imm=%imm_call
>     JMP             1001 010. .... 110.     imm=%imm_call
> 
>     # The 16-bit immediate is completely in the next word.
>     # Fields cannot be defined with no bits, so we cannot play
>     # the same trick and append to a zero-bit value.
>     # Defer reading the immediate until trans_{LDS,STS}.
>     @ldst_s         .... ... rd:5 ....      imm=0
>     LDS             1001 000 ..... 0000     @ldst_s
>     STS             1001 001 ..... 0000     @ldst_s
> 
> 
>     static uint16_t next_word(DisasContext *ctx)
>     {
>         return cpu_lduw_code(ctx->env, ctx->npc++ * 2);
>     }
> 
>     static int append_16(DisasContext *ctx, int x)
>     {
>         return x << 16 | next_word(ctx);
>     }
> 
>     static bool trans_LDS(DisasContext *ctx, arg_ldst_s *a)
>     {
>         a->imm = next_word(ctx);
>         // other stuff
>     }
> 
>     I realize that next_word as written does not fit in to how you currently
>     process instructions in the loop, but I also think that's a mistake.  I'll
>     respond to that in its place in the next patch.
> 
>     That said, next_word *could* be written to use ctx->inst[0].opcode.
> 
> 
>     r~
> 
> 
> 
> -- 
> Best Regards,
> Michael Rolnik
diff mbox series

Patch

diff --git a/target/avr/insn16.decode b/target/avr/insn16.decode
new file mode 100644
index 0000000000..e1cf56c6ae
--- /dev/null
+++ b/target/avr/insn16.decode
@@ -0,0 +1,160 @@ 
+#
+#   A = [16 .. 31]
+#   B = [16 .. 23]
+#   C = [24, 26, 28, 30]
+#   D = [0, 2, 4, 6, 8, .. 30]
+
+%rd             4:5
+%rr             9:1 0:4
+
+&rd_rr          rd rr
+&rd_imm         rd imm
+
+@op_rd_rr       .... .. . ..... ....        &rd_rr      rd=%rd rr=%rr
+ADD             0000 11 . ..... ....        @op_rd_rr
+ADC             0001 11 . ..... ....        @op_rd_rr
+AND             0010 00 . ..... ....        @op_rd_rr
+CP              0001 01 . ..... ....        @op_rd_rr
+CPC             0000 01 . ..... ....        @op_rd_rr
+CPSE            0001 00 . ..... ....        @op_rd_rr
+EOR             0010 01 . ..... ....        @op_rd_rr
+MOV             0010 11 . ..... ....        @op_rd_rr
+MUL             1001 11 . ..... ....        @op_rd_rr
+OR              0010 10 . ..... ....        @op_rd_rr
+SBC             0000 10 . ..... ....        @op_rd_rr
+SUB             0001 10 . ..... ....        @op_rd_rr
+
+
+%rd_c           4:2                         !function=to_C
+%imm6           6:2 0:4
+
+@op_rd_imm6     .... .... .. .. ....        &rd_imm     rd=%rd_c imm=%imm6
+ADIW            1001 0110 .. .. ....        @op_rd_imm6
+SBIW            1001 0111 .. .. ....        @op_rd_imm6
+
+
+%rd_a           4:4                         !function=to_A
+%rr_a           0:4                         !function=to_A
+%rd_d           4:4                         !function=to_D
+%rr_d           0:4                         !function=to_D
+%imm8           8:4 0:4
+
+@op_rd_imm8     .... .... .... ....         &rd_imm     rd=%rd_a imm=%imm8
+ANDI            0111 .... .... ....         @op_rd_imm8
+CPI             0011 .... .... ....         @op_rd_imm8
+LDI             1110 .... .... ....         @op_rd_imm8
+ORI             0110 .... .... ....         @op_rd_imm8
+SBCI            0100 .... .... ....         @op_rd_imm8
+SUBI            0101 .... .... ....         @op_rd_imm8
+
+
+@op_rd          .... ... rd:5 ....
+ASR             1001 010 ..... 0101         @op_rd
+COM             1001 010 ..... 0000         @op_rd
+DEC             1001 010 ..... 1010         @op_rd
+ELPM2           1001 000 ..... 0110         @op_rd
+ELPMX           1001 000 ..... 0111         @op_rd
+INC             1001 010 ..... 0011         @op_rd
+LDX1            1001 000 ..... 1100         @op_rd
+LDX2            1001 000 ..... 1101         @op_rd
+LDX3            1001 000 ..... 1110         @op_rd
+LDY2            1001 000 ..... 1001         @op_rd
+LDY3            1001 000 ..... 1010         @op_rd
+LDZ2            1001 000 ..... 0001         @op_rd
+LDZ3            1001 000 ..... 0010         @op_rd
+LPM2            1001 000 ..... 0100         @op_rd
+LPMX            1001 000 ..... 0101         @op_rd
+LSR             1001 010 ..... 0110         @op_rd
+NEG             1001 010 ..... 0001         @op_rd
+POP             1001 000 ..... 1111         @op_rd
+PUSH            1001 001 ..... 1111         @op_rd
+ROR             1001 010 ..... 0111         @op_rd
+STY2            1001 001 ..... 1001         @op_rd
+STY3            1001 001 ..... 1010         @op_rd
+STZ2            1001 001 ..... 0001         @op_rd
+STZ3            1001 001 ..... 0010         @op_rd
+SWAP            1001 010 ..... 0010         @op_rd
+
+
+@op_bit         .... .... . bit:3 ....
+BCLR            1001 0100 1 ... 1000        @op_bit
+BSET            1001 0100 0 ... 1000        @op_bit
+
+
+@op_rd_bit      .... ... rd:5 . bit:3
+BLD             1111 100 ..... 0 ...        @op_rd_bit
+BST             1111 101 ..... 0 ...        @op_rd_bit
+
+
+@op_bit_imm     .... .. imm:s7 bit:3
+BRBC            1111 01 ....... ...         @op_bit_imm
+BRBS            1111 00 ....... ...         @op_bit_imm
+
+
+BREAK           1001 0101 1001 1000
+EICALL          1001 0101 0001 1001
+EIJMP           1001 0100 0001 1001
+ELPM1           1001 0101 1101 1000
+ICALL           1001 0101 0000 1001
+IJMP            1001 0100 0000 1001
+LPM1            1001 0101 1100 1000
+NOP             0000 0000 0000 0000
+RET             1001 0101 0000 1000
+RETI            1001 0101 0001 1000
+SLEEP           1001 0101 1000 1000
+SPM             1001 0101 1110 1000
+SPMX            1001 0101 1111 1000
+WDR             1001 0101 1010 1000
+
+
+@op_reg_bit     .... .... reg:5 bit:3
+CBI             1001 1000 ..... ...         @op_reg_bit
+SBI             1001 1010 ..... ...         @op_reg_bit
+SBIC            1001 1001 ..... ...         @op_reg_bit
+SBIS            1001 1011 ..... ...         @op_reg_bit
+
+
+DES             1001 0100 imm:4 1011
+
+
+%rd_b           4:3                         !function=to_B
+%rr_b           0:3                         !function=to_B
+@fmul           .... .... . ... . ...       &rd_rr      rd=%rd_b rr=%rr_b
+FMUL            0000 0011 0 ... 1 ...       @fmul
+FMULS           0000 0011 1 ... 0 ...       @fmul
+FMULSU          0000 0011 1 ... 1 ...       @fmul
+MULSU           0000 0011 0 ... 0 ...       @fmul
+
+
+%io_imm         9:2 0:4
+@io_rd_imm      .... . .. ..... ....        &rd_imm     rd=%rd imm=%io_imm
+IN              1011 0 .. ..... ....        @io_rd_imm
+OUT             1011 1 .. ..... ....        @io_rd_imm
+
+
+XCH             1001 001 rd:5 0100
+LAC             1001 001 rd:5 0110
+LAS             1001 001 rd:5 0101
+LAT             1001 001 rd:5 0111
+STX1            1001 001 rr:5 1100
+STX2            1001 001 rr:5 1101
+STX3            1001 001 rr:5 1110
+
+
+%ldst_d_imm     13:1 10:2 0:3
+@ldst_d         .. . . .. . rd:5  . ...     &rd_imm     imm=%ldst_d_imm
+LDDY            10 . 0 .. 0 ..... 1 ...     @ldst_d
+LDDZ            10 . 0 .. 0 ..... 0 ...     @ldst_d
+STDY            10 . 0 .. 1 ..... 1 ...     @ldst_d
+STDZ            10 . 0 .. 1 ..... 0 ...     @ldst_d
+
+
+MOVW            0000 0001 .... ....         &rd_rr      rd=%rd_d rr=%rr_d
+MULS            0000 0010 .... ....         &rd_rr      rd=%rd_a rr=%rr_a
+
+RCALL           1101 imm:s12
+RJMP            1100 imm:s12
+
+SBRC            1111 110 rr:5 0 bit:3
+SBRS            1111 111 rr:5 0 bit:3
+
diff --git a/target/avr/insn32.decode b/target/avr/insn32.decode
new file mode 100644
index 0000000000..f8660dba60
--- /dev/null
+++ b/target/avr/insn32.decode
@@ -0,0 +1,10 @@ 
+%imm        20:5 0:17
+@op_imm22   .... ... ..... ... .................    %imm
+CALL        1001 010 ..... 111 .................    @op_imm22
+JMP         1001 010 ..... 110 .................    @op_imm22
+
+
+@ldst_s     .... ... rd:5  .... imm:16
+LDS         1001 000 ..... 0000 ................    @ldst_s
+STS         1001 001 ..... 0000 ................    @ldst_s
+