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
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
+
--
2.18.0
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,
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~
>
--
Best Regards,
Michael Rolnik
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
© 2016 - 2026 Red Hat, Inc.