From e606772aeb177c67d4c08b42ba79ef196906e1d7 Mon Sep 17 00:00:00 2001 From: Shawn Anastasio Date: Mon, 25 May 2020 20:03:02 -0500 Subject: [PATCH 1/2] Implement the addpcis instruction This commit adds support for the addpcis instruction from ISA 3.0. A new input_reg_b_t type, CONST_DX_HI, was added to support the shifted immediate value used in DX-Form instructions. Signed-off-by: Shawn Anastasio --- decode1.vhdl | 4 ++-- decode2.vhdl | 2 ++ decode_types.vhdl | 2 +- execute1.vhdl | 3 +++ insn_helpers.vhdl | 6 ++++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index 4cd195f..5eedbab 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -106,8 +106,8 @@ architecture behaviour of decode1 is -- op in out A out in out len ext pipe -- mcrf; and cr logical ops 2#000# => (ALU, OP_CROP, NONE, NONE, NONE, NONE, '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), - -- addpcis not implemented yet - 2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + -- addpcis + 2#001# => (ALU, OP_ADDPCIS, NONE, CONST_DX_HI, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- bclr, bcctr, bctar 2#100# => (ALU, OP_BCREG, SPR, SPR, NONE, SPR, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'), -- isync diff --git a/decode2.vhdl b/decode2.vhdl index b239392..da0bdff 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -100,6 +100,8 @@ architecture behaviour of decode2 is ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_bd(insn_in)) & "00", 64))); when CONST_DS => ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_ds(insn_in)) & "00", 64))); + when CONST_DX_HI => + ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_dx(insn_in)) & x"0000", 64))); when CONST_M1 => ret := ('0', (others => '0'), x"FFFFFFFFFFFFFFFF"); when CONST_SH => diff --git a/decode_types.vhdl b/decode_types.vhdl index 8f000a0..bd16507 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -21,7 +21,7 @@ package decode_types is OP_FETCH_FAILED ); type input_reg_a_t is (NONE, RA, RA_OR_ZERO, SPR); - type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR); + type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DX_HI, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR); type input_reg_c_t is (NONE, RS); type output_reg_a_t is (NONE, RT, RA, SPR); type rc_t is (NONE, ONE, RC); diff --git a/execute1.vhdl b/execute1.vhdl index feb8581..d8854ae 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -528,6 +528,9 @@ begin end if; when OP_NOP => -- Do nothing + when OP_ADDPCIS => + result := ppc_adde(next_nia, b_in, '0')(63 downto 0); + result_en := '1'; when OP_ADD | OP_CMP | OP_TRAP => if e_in.invert_a = '0' then a_inv := a_in; diff --git a/insn_helpers.vhdl b/insn_helpers.vhdl index 8812044..acd2f72 100644 --- a/insn_helpers.vhdl +++ b/insn_helpers.vhdl @@ -30,6 +30,7 @@ package insn_helpers is function insn_bh (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_d (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_ds (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_dx (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_to (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_bc (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_sh (insn_in : std_ulogic_vector) return std_ulogic_vector; @@ -178,6 +179,11 @@ package body insn_helpers is return insn_in(15 downto 2); end; + function insn_dx (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(15 downto 6) & insn_in(20 downto 16) & insn_in(0); + end; + function insn_to (insn_in : std_ulogic_vector) return std_ulogic_vector is begin return insn_in(25 downto 21); From 8b161c6dc6070f186cfe6ccd23466ff448d03c5b Mon Sep 17 00:00:00 2001 From: Shawn Anastasio Date: Mon, 25 May 2020 20:08:59 -0500 Subject: [PATCH 2/2] Add a new misc test suite with addpcis tests The two tests obtain NIA with bl+mflr+addi and then compare it against addpcis with the minimum and maximum immediate operand values. They were also tested on a real POWER9 system (in userspace) for good measure. Signed-off-by: Shawn Anastasio --- tests/misc/Makefile | 3 ++ tests/misc/head.S | 102 ++++++++++++++++++++++++++++++++++++ tests/misc/misc.c | 44 ++++++++++++++++ tests/misc/powerpc.lds | 13 +++++ tests/test_misc.bin | Bin 0 -> 5208 bytes tests/test_misc.console_out | 2 + tests/update_console_tests | 2 +- 7 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 tests/misc/Makefile create mode 100644 tests/misc/head.S create mode 100644 tests/misc/misc.c create mode 100644 tests/misc/powerpc.lds create mode 100755 tests/test_misc.bin create mode 100644 tests/test_misc.console_out diff --git a/tests/misc/Makefile b/tests/misc/Makefile new file mode 100644 index 0000000..3f92384 --- /dev/null +++ b/tests/misc/Makefile @@ -0,0 +1,3 @@ +TEST=misc + +include ../Makefile.test diff --git a/tests/misc/head.S b/tests/misc/head.S new file mode 100644 index 0000000..9eb752c --- /dev/null +++ b/tests/misc/head.S @@ -0,0 +1,102 @@ +/* Copyright 2013-2014 IBM Corp. + * Copyrignt 2020 Shawn Anastasio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define STACK_TOP 0x2000 + +/* Load an immediate 64-bit value into a register */ +#define LOAD_IMM64(r, e) \ + lis r,(e)@highest; \ + ori r,r,(e)@higher; \ + rldicr r,r, 32, 31; \ + oris r,r, (e)@h; \ + ori r,r, (e)@l; + + .section ".head","ax" + + /* + * Microwatt currently enters in LE mode at 0x0, so we don't need to + * do any endian fix ups + */ + . = 0 +.global _start +_start: + b boot_entry + +.global boot_entry +boot_entry: + /* setup stack */ + LOAD_IMM64(%r1, STACK_TOP - 0x100) + LOAD_IMM64(%r12, main) + mtctr %r12 + bctrl + attn // terminate on exit + b . + + +/* Test addpcis with an immediate operand of 0 (min) */ +.global test_addpcis_1 +test_addpcis_1: + mflr %r0 + std %r0, 16(%r1) + stdu %r1, -32(%r1) + + /* get address of 1 */ + bl 1f + 1: mflr %r4 + addpcis %r5, 0 + + /* + * At this point, r5 should equal r4 + 2*4 + * return 0 if they're equal. + */ + addi %r4, %r4, 8 + + sub %r3, %r4, %r5 + + addi %r1, %r1, 32 + ld %r0, 16(%r1) + mtlr %r0 + + blr + +/* Test addpcis with an immediate operand of 0xFFFF (max) */ +.global test_addpcis_2 +test_addpcis_2: + mflr %r0 + std %r0, 16(%r1) + stdu %r1, -32(%r1) + + /* get address of 1 */ + bl 1f + 1: mflr %r4 + addpcis %r5, 0xFFFF + + /* + * Add 8 to r4 to bring it in line with addpcis' NIA. + * Then add 0xFFFF shifted and compare. + */ + addi %r4, %r4, 8 + addis %r4, %r4, 0xFFFF + + sub %r3, %r4, %r5 + + addi %r1, %r1, 32 + ld %r0, 16(%r1) + mtlr %r0 + + blr + diff --git a/tests/misc/misc.c b/tests/misc/misc.c new file mode 100644 index 0000000..0b9079c --- /dev/null +++ b/tests/misc/misc.c @@ -0,0 +1,44 @@ +#include +#include +#include + +#include "console.h" + +#define TEST "Test " +#define PASS "PASS\n" +#define FAIL "FAIL\n" + +extern long test_addpcis_1(void); +extern long test_addpcis_2(void); + +// i < 100 +void print_test_number(int i) +{ + puts(TEST); + putchar(48 + i/10); + putchar(48 + i%10); + putchar(':'); +} + +int main(void) +{ + int fail = 0; + + potato_uart_init(); + + print_test_number(1); + if (test_addpcis_1() != 0) { + fail = 1; + puts(FAIL); + } else + puts(PASS); + + print_test_number(2); + if (test_addpcis_2() != 0) { + fail = 1; + puts(FAIL); + } else + puts(PASS); + + return fail; +} diff --git a/tests/misc/powerpc.lds b/tests/misc/powerpc.lds new file mode 100644 index 0000000..0b65470 --- /dev/null +++ b/tests/misc/powerpc.lds @@ -0,0 +1,13 @@ +SECTIONS +{ + _start = .; + . = 0; + .head : { + KEEP(*(.head)) + } + . = 0x1000; + .text : { *(.text) } + . = 0x2000; + .data : { *(.data) } + .bss : { *(.bss) } +} diff --git a/tests/test_misc.bin b/tests/test_misc.bin new file mode 100755 index 0000000000000000000000000000000000000000..a32d52ca137639fc3457f722191f047fd846a309 GIT binary patch literal 5208 zcmeHLJxo(k6h61qQYw(THNn8EI<%%k$A=X19wI?NtkT4|y;7Qp8^NKNSNdom(S*dr zFawLkL7f;JOw<^e9At462n$GzOO+u&V{d39Xx~JKo+ZrMlvGgswyr!Q-aZ?71=j{0t z(@jf*UYb$kO4?K?sKUOzT<68VHFTQ)XZhatmvSZ+4~_m6W3S|V90nW)90nW)90nW) z90nW)90nW)90nW)90nW){)>Tv{J6_^^rGC{t=`iGX)#*rR{6dTdkMBure(^MawO)X zjgHVnitqKsHQf8hT>O4O#<$X8E=oDoN3w0DK4msl@OU9-Mk%E-wkOKI*T_(RR{o=S zBS7MTN)y7u+d}R7ymoc1*Y;Zl83OTX#7zIP;|!w9kvQdbu1}!8DC%3QKZca-MbbJ+=}$f%4rj^g-U(1Y$_=;M_IpZ}-%XI`k5sto(Rj3v15v-;(; z$Y+7iqm)}6)iWVz{TWeL#7}vR&k|@+BL{N8N3EeoU`?1$V~;YwKjkK&zt-*-&RVAB zp~*3C0#~y{4H1R%w*>ks9Q&bNqC|S)kpkVT-yHNo$MxZ1)_x2Y@%S#eGrDML6m$ji z0LI&WDJ^Ka(V)|UYf