cpu32

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit c56a07483d3776294346b62851a9ec0ea65f6c5b
parent 796c3cd6166d1d349d1abbe77bb715d57a351cef
Author: Brian Swetland <swetland@frotz.net>
Date:   Sat, 11 Feb 2012 00:45:42 -0800

oops: branch relative and branch indirect need their own opcodes

Otherwise I'd need a 9th bit in the control decoder and more logic.

Diffstat:
Ma32.c | 16++++++++--------
Mde0nano/fw.s | 21++++++++++-----------
Misa.txt | 4++--
Atests/0025-subroutine.s | 10++++++++++
Atests/0025-subroutine.s.gold | 12++++++++++++
Mverilog/control.v | 3++-
6 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/a32.c b/a32.c @@ -450,14 +450,14 @@ struct { { 0xFFFF0000, 0x40FE0000, "BL @r", }, { 0xFF0F0000, 0x400F0000, "BZ @A, @r", }, { 0xFF0F0000, 0x400E0000, "BLZ @A, @r", }, - { 0xFFF0F000, 0x44F0F000, "B @B", }, - { 0xFFF0F000, 0x44F0E000, "BL @B", }, - { 0xFF00F000, 0x4400F000, "BZ @A, @B", }, - { 0xFF00F000, 0x4400E000, "BLZ @A, @B", }, + { 0xFFF0F000, 0x50F0F000, "B @B", }, + { 0xFFF0F000, 0x50F0E000, "BL @B", }, + { 0xFF00F000, 0x5000F000, "BZ @A, @B", }, + { 0xFF00F000, 0x5000E000, "BLZ @A, @B", }, { 0xFF0F0000, 0x480F0000, "BNZ @A, @r", }, { 0xFF0F0000, 0x480E0000, "BLNZ @A, @r", }, - { 0xFF00F000, 0x4800F000, "BNZ @A, @B", }, - { 0xFF00F000, 0x4800E000, "BLNZ @A, @B", }, + { 0xFF00F000, 0x5800F000, "BNZ @A, @B", }, + { 0xFF00F000, 0x5800E000, "BLNZ @A, @B", }, { 0x00000000, 0x00000000, "UNDEFINED", }, }; @@ -535,7 +535,7 @@ void assemble_line(int n, unsigned *tok, unsigned *num, char **str) { tmp = 14; } if (is_register(tok[1])) { - emit(0x44F00000 | TO_D(tmp) | TO_B(to_register(tok[1]))); + emit(0x50F00000 | TO_D(tmp) | TO_B(to_register(tok[1]))); } else if (tok[1] == tSTRING) { emit(0x40F00000 | TO_B(tmp)); uselabel(str[1], PC - 1, 16); @@ -560,7 +560,7 @@ void assemble_line(int n, unsigned *tok, unsigned *num, char **str) { expect(tCOMMA,tok[2]); instr |= TO_A(to_register(tok[1])); if (is_register(tok[3])) { - emit(instr | 0x04000000 | TO_D(tmp) | TO_B(to_register(tok[3]))); + emit(instr | 0x10000000 | TO_D(tmp) | TO_B(to_register(tok[3]))); } else if (tok[3] == tSTRING) { emit(instr | TO_B(tmp)); uselabel(str[3], PC - 1, 16); diff --git a/de0nano/fw.s b/de0nano/fw.s @@ -1,6 +1,6 @@ NOP - MOV R14, 0xF0000000 - MOV R13, 0xE0000000 + MOV R12, 0xF0000000 + MOV R11, 0xE0000000 MOV R0, 0x30 BL uart_send @@ -14,25 +14,24 @@ MOV R0, 0 MOV R2, 256 xmit_loop: - SW R0, [R14] + SW R0, [R12] wait_fifo: - LW R1, [R13] + LW R1, [R11] BNZ R1, wait_fifo - SW R0, [R13] + SW R0, [R11] ADD R0, R0, 1 SUB R2, R2, 1 BNZ R2, xmit_loop MOV R0, 0 - SW R0, [R14] + SW R0, [R12] B . uart_send: - MOV R13, 0xE0000000 + MOV R11, 0xE0000000 uart_wait: - LW R12, [R13] + LW R12, [R11] BNZ R12, uart_wait - SW R0, [R13] - B R15 - + SW R0, [R11] + B LR diff --git a/isa.txt b/isa.txt @@ -17,9 +17,9 @@ Core Instruction Set 32 SW Rd, [Ra, #I] M(Ra + I) = Rd 40 BLZ Rd, Ra, rel if (Ra == 0) { Rd = PC + 4, PC += I } -44 BLZ Rd, Ra, Rb if (Ra == 0) { Rd = PC + 4, PC = Rb } 48 BLNZ Rd, Ra, rel if (Ra != 0) { Rd = PC + 4, PC += I } -4C BLNZ Rd, Ra, Rb if (Ra != 0) { Rd = PC + 4, PC = Rb } +50 BLZ Rd, Ra, Rb if (Ra == 0) { Rd = PC + 4, PC = Rb } +58 BLNZ Rd, Ra, Rb if (Ra != 0) { Rd = PC + 4, PC = Rb } Extended Instruction Set (tbd) ------------------------ diff --git a/tests/0025-subroutine.s b/tests/0025-subroutine.s @@ -0,0 +1,10 @@ +NOP +MOV R0, 0x12345678 +BL test +MOV R1, 0x77777777 +NOP +WORD 0xFFFFFFFF +test: +MOV R2, 0x11111111 +ADD R0, R0, R2 +B LR diff --git a/tests/0025-subroutine.s.gold b/tests/0025-subroutine.s.gold @@ -0,0 +1,12 @@ +PC> 00000000 I> 00000000 R> xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx +PC> 00000004 I> 1df01234 R> xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx +PC> 00000008 I> 1c005678 R> 12340000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx +PC> 0000000c I> 40fe0005 R> 12345678 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx +PC> 00000020 I> 1df21111 R> 12345678 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 00000010 +PC> 00000024 I> 1c221111 R> 12345678 xxxxxxxx 11110000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 00000010 +PC> 00000028 I> 02020000 R> 12345678 xxxxxxxx 11111111 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 00000010 +PC> 0000002c I> 50fef000 R> 23456789 xxxxxxxx 11111111 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 00000010 +PC> 00000010 I> 1df17777 R> 23456789 xxxxxxxx 11111111 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 00000010 +PC> 00000014 I> 1c117777 R> 23456789 77770000 11111111 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 00000010 +PC> 00000018 I> 00000000 R> 23456789 77777777 11111111 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 00000010 +PC> EXIT diff --git a/verilog/control.v b/verilog/control.v @@ -29,6 +29,7 @@ always @ (*) 4'b0010: control = 8'b01101001; // LW Rd, [Ra, #I] 4'b0011: control = 8'b01010000; // SW Rd, [Ra, #I] 4'b0100: control = 8'b10101110; // B rel16 + 4'b0101: control = 8'b10100110; // B Rb default: control = 8'b00000000; endcase @@ -38,7 +39,7 @@ assign { } = control[7:0]; assign ctl_branch_nz = opfunc[3]; -assign ctl_branch_ind = opfunc[2]; +assign ctl_branch_ind = opcode[0]; assign ctl_branch_taken = (ctl_branch_op & (ctl_adata_zero != ctl_branch_nz)); endmodule