From 88fd7b3cdc0f1746e21705eededf17823edfe1fd Mon Sep 17 00:00:00 2001 From: David Given Date: Fri, 8 Mar 2019 23:06:34 +0100 Subject: [PATCH] Add a 'kill' pseudoinstruction to the 8080 assembler, which marks when the code generator is finished with a register; use this to create some more effective peephole optimiser rules. --- mach/i80/as/mach2.c | 2 ++ mach/i80/as/mach3.c | 6 ++++ mach/i80/as/mach4.c | 3 +- mach/i80/ncg/table | 63 ++++++++++++++++++++++++++++++++++++-- mach/i80/top/table | 33 ++++++++++++++++++++ tests/plat/core/and_e.e | 14 +++++++++ tests/plat/core/intadd_e.c | 2 ++ tests/plat/core/intsub_e.c | 3 ++ tests/plat/core/ior_e.e | 14 +++++++++ tests/plat/core/xor_e.e | 14 +++++++++ 10 files changed, 151 insertions(+), 3 deletions(-) diff --git a/mach/i80/as/mach2.c b/mach/i80/as/mach2.c index 715605b15..4c4a90480 100644 --- a/mach/i80/as/mach2.c +++ b/mach/i80/as/mach2.c @@ -21,3 +21,5 @@ %token STLDAX %type r16 r8 + +%token KILL diff --git a/mach/i80/as/mach3.c b/mach/i80/as/mach3.c index a0001b2dd..94b531d2e 100644 --- a/mach/i80/as/mach3.c +++ b/mach/i80/as/mach3.c @@ -4,6 +4,12 @@ */ #define RCSID3 "$Id$" +/* + * Specials + */ + +0, KILL, 0, "kill", + /* * Intel 8080 keywords */ diff --git a/mach/i80/as/mach4.c b/mach/i80/as/mach4.c index 8caa5cf87..27a3e7404 100644 --- a/mach/i80/as/mach4.c +++ b/mach/i80/as/mach4.c @@ -10,7 +10,8 @@ * Intel 8080 parsing rules */ operation - : NOOPOP + : KILL REG {} + | NOOPOP { emit1($1);} | D8OP expr diff --git a/mach/i80/ncg/table b/mach/i80/ncg/table index 9eea4b76a..74c85f89e 100644 --- a/mach/i80/ncg/table +++ b/mach/i80/ncg/table @@ -48,6 +48,7 @@ TOKENS const1 = { INT num; } 1 num. const2 = { INT num; } 2 num. +largeconst2 = { INT num; } 2 num. /* Word-sized constant with low byte zero */ smallpconst2 = { INT num; } 2 num. /* Byte-sized positive constant */ smallnconst2 = { INT num; } 2 num. /* Byte-sized negative constant */ label = { ADDR off; } 2 off. @@ -60,17 +61,18 @@ SETS reg1 = reg + lbreg + m. b_d_h_sp = regpair + stackpointer. b_d_h_psw = regpair + psword. -immediate = smallpconst2 + smallnconst2 + const2 + label. +immediate = largeconst2 + smallpconst2 + smallnconst2 + const2 + label. src1 = reg. src2 = hl_or_de + const2 + label. src1or2 = src1 + src2. +anyreg = reg + regpair. INSTRUCTIONS /* aci const1:ro kills a:cc cost(2, 7). */ adc reg1:ro kills a:cc cost(1, 4). add reg1:ro kills a:cc cost(1, 4). -/* adi const1:ro kills a:cc cost(2, 7). */ + adi const1:ro kills a:cc cost(2, 7). ana reg1:ro kills a:cc cost(1, 4). ani const1:ro kills a:cc cost(2, 7). Call "call" label:ro cost(3,17). @@ -154,6 +156,7 @@ INSTRUCTIONS xri const1:ro kills a:cc cost(2, 7). xthl kills hl cost(1,18). + kill anyreg:rw kills :cc cost(0, 0). MOVES @@ -261,6 +264,9 @@ COERCIONS from hl_or_de yields %1.2 + from largeconst2 + yields {const2, %1.num} + from smallpconst2 yields {const2, %1.num} @@ -271,6 +277,10 @@ COERCIONS uses hl_or_de=%1 yields %a + from largeconst2 + uses hl_or_de=%1 + yields %a + from smallpconst2 uses reg={const1, %1.num & 0xff} yields %a @@ -305,6 +315,9 @@ PATTERNS /* Group 1: Load instructions */ /*********************************************/ +pat loc ($1 != 0) && (($1 & 0xff) == 0) + yields {largeconst2, $1} + pat loc ufit($1, 8) yields {smallpconst2, $1} @@ -727,6 +740,18 @@ pat sde /****************************************/ pat adi $1==2 + with hl_or_de largeconst2 + uses areg + gen + mov a, %1.1 + adi {const1, %2.num >> 8} + mov %1.1, a + kill a + yields %1 + with largeconst2 hl_or_de + yields %1 %2 + leaving + adi 2 with hlreg dereg gen dad de @@ -755,6 +780,14 @@ pat sbi $1==2 yields %2 {const2, 0-%1.num} leaving adi 2 + with largeconst2 hl_or_de + yields %2 {largeconst2, 0-%1.num} + leaving + adi 2 + with smallpconst2 hl_or_de + yields %2 {smallnconst2, 0-%1.num} + leaving + adi 2 with smallnconst2 hl_or_de yields %2 {smallpconst2, 0-%1.num} leaving @@ -768,6 +801,7 @@ pat sbi $1==2 mvi a, {const1, %2.num >> 8} sbb %1.1 mov %1.1, a + kill a yields %1 with hl_or_de hl_or_de uses areg @@ -778,6 +812,7 @@ pat sbi $1==2 mov a,%2.1 sbb %1.1 mov %1.1,a + kill a yields %1 with hl_or_de hl_or_de uses areg @@ -788,6 +823,7 @@ pat sbi $1==2 mov a,%2.1 sbb %1.1 mov %2.1,a + kill a yields %2 pat sbi $1==4 @@ -1282,6 +1318,7 @@ pat and $1==2 mov a, %1.2 ani {const1, %2.num & 0xff} mov %1.2, a + kill a yields %1 with smallnconst2 hl_or_de yields %1 %2 @@ -1293,9 +1330,11 @@ pat and $1==2 mov a, %1.2 ani {const1, %2.num & 0xff} mov %1.2, a + kill a mov a, %1.1 ani {const1, %2.num >> 8} mov %1.1, a + kill a yields %1 with const2 hl_or_de yields %1 %2 @@ -1307,9 +1346,11 @@ pat and $1==2 mov a, %1.2 ana %2.2 mov %2.2, a + kill a mov a, %1.1 ana %2.1 mov %2.1, a + kill a yields %2 with hl_or_de hl_or_de uses areg @@ -1317,9 +1358,11 @@ pat and $1==2 mov a,%1.2 ana %2.2 mov %1.2,a + kill a mov a,%1.1 ana %2.1 mov %1.1,a + kill a yields %1 pat and defined($1) @@ -1343,6 +1386,7 @@ pat ior $1==2 mov a, %1.2 ori {const1, %2.num & 0xff} mov %1.2, a + kill a yields %1 with smallpconst2 hl_or_de yields %1 %2 @@ -1354,6 +1398,7 @@ pat ior $1==2 mov a, %1.2 ori {const1, %2.num & 0xff} mov %1.2, a + kill a move {const1, 0xff}, %1.1 yields %1 with smallnconst2 hl_or_de @@ -1366,9 +1411,11 @@ pat ior $1==2 mov a, %1.2 ori {const1, %2.num & 0xff} mov %1.2, a + kill a mov a, %1.1 ori {const1, %2.num >> 8} mov %1.1, a + kill a yields %1 with const2 hl_or_de yields %1 %2 @@ -1380,9 +1427,11 @@ pat ior $1==2 mov a, %1.2 ora %2.2 mov %2.2, a + kill a mov a, %1.1 ora %2.1 mov %2.1, a + kill a yields %2 with hl_or_de hl_or_de uses areg @@ -1390,9 +1439,11 @@ pat ior $1==2 mov a,%1.2 ora %2.2 mov %1.2,a + kill a mov a,%1.1 ora %2.1 mov %1.1,a + kill a yields %1 pat ior defined($1) @@ -1414,6 +1465,7 @@ pat xor $1==2 mov a, %1.2 xri {const1, %2.num & 0xff} mov %1.2, a + kill a yields %1 with smallpconst2 hl_or_de yields %1 %2 @@ -1425,9 +1477,11 @@ pat xor $1==2 mov a, %1.2 xri {const1, %2.num & 0xff} mov %1.2, a + kill a mov a, %1.1 xri {const1, %2.num >> 8} mov %1.1, a + kill a yields %1 with const2 hl_or_de yields %1 %2 @@ -1439,9 +1493,11 @@ pat xor $1==2 mov a, %1.2 xra %2.2 mov %2.2, a + kill a mov a, %1.1 xra %2.1 mov %2.1, a + kill a yields %2 with hl_or_de hl_or_de uses areg @@ -1449,9 +1505,11 @@ pat xor $1==2 mov a,%1.2 xra %2.2 mov %1.2,a + kill a mov a,%1.1 xra %2.1 mov %1.1,a + kill a yields %1 pat xor defined($1) @@ -1470,6 +1528,7 @@ uses areg gen mov a,%1.2 cma. mov %1.2,a + kill a mov a,%1.1 cma. mov %1.1,a yields %1 diff --git a/mach/i80/top/table b/mach/i80/top/table index 3e0c20d43..3423c3791 100644 --- a/mach/i80/top/table +++ b/mach/i80/top/table @@ -26,4 +26,37 @@ push d : lxi d, X : pop h -> lxi h, X : xchg ; push h : lhld X : pop d -> xchg : lhld X ; +X -1 -> X 255 ; +X -2 -> X 254 ; +X -3 -> X 253 ; +X -4 -> X 252 ; + +mov a, X : adi -4 : mov X, a : kill a -> dcr X : dcr X : dcr X : dcr X; +mov a, X : adi -3 : mov X, a : kill a -> dcr X : dcr X : dcr X ; +mov a, X : adi -2 : mov X, a : kill a -> dcr X : dcr X ; +mov a, X : adi -1 : mov X, a : kill a -> dcr X ; +mov a, X : adi 0 : mov X, a : kill a -> ; +mov a, X : adi 1 : mov X, a : kill a -> inr X ; +mov a, X : adi 2 : mov X, a : kill a -> inr X : inr X ; +mov a, X : adi 3 : mov X, a : kill a -> inr X : inr X : inr X ; +mov a, X : adi 4 : mov X, a : kill a -> inr X : inr X : inr X : inr X; + +mov a, X : sbi -4 : mov X, a : kill a -> inr X : inr X : inr X : inr X; +mov a, X : sbi -3 : mov X, a : kill a -> inr X : inr X : inr X ; +mov a, X : sbi -2 : mov X, a : kill a -> inr X : inr X ; +mov a, X : sbi -1 : mov X, a : kill a -> inr X ; +mov a, X : sbi 0 : mov X, a : kill a -> ; +mov a, X : sbi 1 : mov X, a : kill a -> dcr X ; +mov a, X : sbi 2 : mov X, a : kill a -> dcr X : dcr X ; +mov a, X : sbi 3 : mov X, a : kill a -> dcr X : dcr X : dcr X ; +mov a, X : sbi 4 : mov X, a : kill a -> dcr X : dcr X : dcr X : dcr X ; + +mov a, X : ani 0 : mov X, a : kill a -> mvi X, 0 ; +mov a, X : ani 255 : mov X, a : kill a -> ; + +mov a, X : ori 0 : mov X, a : kill a -> ; +mov a, X : ori 255 : mov X, a : kill a -> mvi X, 255 ; + +mov a, X : xri 0 : mov X, a : kill a -> ; + %%; diff --git a/tests/plat/core/and_e.e b/tests/plat/core/and_e.e index e37a84c6c..0e29de6ad 100644 --- a/tests/plat/core/and_e.e +++ b/tests/plat/core/and_e.e @@ -111,5 +111,19 @@ big asp 4 7 + /* And var with big low-byte-zero const */ + + loe big + loc 256 + and EM_WSIZE + loc 256 + cmu EM_WSIZE + zeq *8 + + loc __LINE__ + cal $fail + asp 4 +8 + cal $finished end diff --git a/tests/plat/core/intadd_e.c b/tests/plat/core/intadd_e.c index 94549814c..bb22bf1ce 100644 --- a/tests/plat/core/intadd_e.c +++ b/tests/plat/core/intadd_e.c @@ -27,5 +27,7 @@ void _m_a_i_n(void) ASSERT(((unsigned int)1 + (unsigned int)two) == 3); ASSERT(((unsigned int)-1 + (unsigned int)two) == 1); + ASSERT(((unsigned int)two + (unsigned int)256) == 258); + finished(); } diff --git a/tests/plat/core/intsub_e.c b/tests/plat/core/intsub_e.c index b0cf08ae6..35341fab0 100644 --- a/tests/plat/core/intsub_e.c +++ b/tests/plat/core/intsub_e.c @@ -6,6 +6,7 @@ int two = 2; int one = 1; int zero = 0; int minusone = -1; +int biggish = 258; /* Bypasses the CRT, so there's no stdio. */ void _m_a_i_n(void) @@ -28,5 +29,7 @@ void _m_a_i_n(void) ASSERT(((unsigned int)2 - (unsigned int)one) == 1); ASSERT(((unsigned int)1 - (unsigned int)two) == UINT_MAX); + ASSERT(((unsigned int)biggish - (unsigned int)256) == 2); + finished(); } diff --git a/tests/plat/core/ior_e.e b/tests/plat/core/ior_e.e index c0e160691..c01be1ca4 100644 --- a/tests/plat/core/ior_e.e +++ b/tests/plat/core/ior_e.e @@ -111,5 +111,19 @@ big asp 4 7 + /* Or var with big low-byte-zero const */ + + loe big + loc 256 + ior EM_WSIZE + loc 258 + cmu EM_WSIZE + zeq *8 + + loc __LINE__ + cal $fail + asp 4 +8 + cal $finished end diff --git a/tests/plat/core/xor_e.e b/tests/plat/core/xor_e.e index 10310964c..ce2ab6af8 100644 --- a/tests/plat/core/xor_e.e +++ b/tests/plat/core/xor_e.e @@ -111,6 +111,20 @@ big asp 4 7 + /* Xor var with big low-byte-zero const */ + + loe big + loc 256 + xor EM_WSIZE + loc 745 + cmu EM_WSIZE + zeq *8 + + loc __LINE__ + cal $fail + asp 4 +8 + cal $finished end -- 2.34.1