Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
98ca3a7
Add Z8001 (Coherent/Commodore 900) architecture backend
Jun 30, 2026
a5ca691
z8001: fix code generation for the Coherent segmented ABI
Jul 2, 2026
1e4ca7f
z8001: variable-count shifts, addressing-mode legality, word alignment
Jul 2, 2026
9770c8d
z8001: struct return by value, byte-register constraints, bitfield fixes
Jul 3, 2026
3abf79b
cxxcom: fix out-of-bounds read in builtin_nanx
Jul 3, 2026
bc6b562
z8001: software floating point (float/double, native Coherent FP runt…
Jul 4, 2026
ed01a29
z8001: make &scalar-local work; FP-printf selection is link-time policy
Jul 4, 2026
34982cc
ccom: K&R parameter fixes and target-selectable sizeof/ptrdiff types
Jul 5, 2026
4a64c14
z8001: fixes from compiling real programs (echo, wc, ls run correct)
Jul 5, 2026
26f693f
z8001: byte register class D (rl0-rl7) replaces byte-insn constraints
Jul 5, 2026
eb84b22
z8001: block return-value coalescing into rr0
Jul 6, 2026
5e9d487
z8001: promote char arguments to int at function calls
Jul 6, 2026
8105b09
ccom: fix chkpun crash on function pointer initialized from cast pointer
Jul 6, 2026
203728e
ccom: accept K&R constructs found throughout Coherent sources
Jul 6, 2026
80e7fe3
ccom: target hook OPTIM_KEEPZERO to protect x+0/x-0 identity folds
Jul 6, 2026
d985695
z8001: frame address at offset zero must stay segmented; fold (long)ptr
Jul 6, 2026
e3e2d85
ccom: check ferror instead of putw return value in pr_wr
Jul 6, 2026
a203f54
ccom: findops xssa 2-op preference must not demote SPECIAL shape matches
Jul 6, 2026
9aeb73a
z8001: push arguments directly from constants, globals and frame slots
Jul 6, 2026
9012124
z8001: truth tests - EQ/NE against zero via test/testl/testb
Jul 6, 2026
97506de
z8001: narrow char equality compares to byte width in clocal
Jul 6, 2026
b2d8f26
z8001: SNBA accepts zero-displacement dereferences as SROREG
Jul 6, 2026
c81529e
z8001: load small word constants with the 2-byte ldk
Jul 6, 2026
7e26e37
z8001: pointer +- constant operates on the offset word only
Jul 7, 2026
b7f1d6d
z8001: byte-op rules - clrb, char-mask andb, subb high-byte zero-extend
Jul 7, 2026
0019c3d
z8001: clocal narrows char compares and mask truth tests to byte width
Jul 7, 2026
a24b2d2
regs.c: PICKCOLOR and SPILLSHADOW target hooks for AssignColors
Jul 7, 2026
4adb918
z8001: callee-save registers allocated top-down (family #6)
Jul 7, 2026
2cf534a
reader/match: CCOKFORCOMP elision gate hook, pure-FORCC findops fix
Jul 7, 2026
6f1b2b4
z8001: gate compare-vs-zero elision to flags the child insn really sets
Jul 7, 2026
9dff336
z8001: bit/bitb rules for single-bit truth tests (family #7)
Jul 7, 2026
fa5b65c
z8001: variable pointer index in the word domain (family #2 extension)
Jul 7, 2026
8cae728
z8001: put compare constants on the right for every width (family #8)
Jul 7, 2026
cc24251
z8001: sign-only test/testl for ordered compares against zero
Jul 7, 2026
bd49863
deljumps: negate the operator when inverting a branch, keep operands
Jul 7, 2026
608f858
regalloc: clear precolored move lists in the onlyperm reset
Jul 7, 2026
c3bc192
relops: honor the cookie, return the result class
Jul 7, 2026
9e2022a
reader: elide the compare against a value just stored
Jul 7, 2026
334ac04
pass1: KEEPLOGOPVALUE hook - keep value-context relationals in the tree
Jul 7, 2026
e0e5bf6
z8001: tcc boolean materialization for value-context relationals
Jul 7, 2026
4108502
z8001: set/res for single-bit or/and (family #9)
Jul 7, 2026
02daba8
z8001: lda X mode for address constant + word index (family #10)
Jul 7, 2026
dc09a22
z8001: fuse ASSIGN with the following compare of the stored value
Jul 7, 2026
108ce90
z8001: shift-left-by-1 as self-add
Jul 7, 2026
399903a
z8001: fusecmp must patch basic-block boundaries when unlinking
Jul 7, 2026
db116c1
mip: implement tail merging (comjump/xjump) in deljumps
Jul 7, 2026
881898e
z8001: recover the RMW compare elision at -O1 (rmwrename)
Jul 7, 2026
c5d0ab1
z8001: steer the lda X index away from r0 (NORIGHT on the ZX rule)
Jul 7, 2026
41d23e3
cc/cpp, cc/ccom: open the output file in binary mode
Jul 7, 2026
0e14a95
cc: make the cross-driver usable for z8001-coherent (Windows host)
Jul 7, 2026
1640638
mip: add SWDISP pass2 op + precise computed-goto CFG edges
Jul 8, 2026
f4b6c4d
z8001: sparse-switch dispatch via the cpir block-search idiom
Jul 8, 2026
6e4f3f4
mip: add BCLR pass2 op (block memory clear)
Jul 8, 2026
757fd71
z8001: compact auto-aggregate zero-fill (BCLR overlapping ldirb)
Jul 8, 2026
9131e45
z8001: shrink switch cpir tables to .word offsets + size-gate it
Jul 8, 2026
dcb2dd2
Add -ftraditional flag to gate K&R leniency (off by default)
Jul 8, 2026
0c3be0b
Revert wb binary output mode in ccom/cpp
Jul 8, 2026
dcd1d25
z8001: integer-promote byte shift counts in clocal
Jul 9, 2026
4ab56b6
z8001: emit frame-base equate as SS|total, not 0|total
Jul 10, 2026
e1e58b7
z8001: djnz loop fusion + SSA dead-source RMW compare elision
Jul 10, 2026
34ad366
z8001: mask segment word after lda in ZX (&arr[i]) escape
Jul 11, 2026
3c2ff73
z8001: smaller long-zero, small-const, and in-place loop-RMW codegen
Jul 13, 2026
c006d7f
z8001: word +/- by 2..16 uses inc/dec instead of add/sub
Jul 13, 2026
f8c90b1
z8001: elide frame setup for r13-unused fns; push/pop for total==2
Jul 13, 2026
a7444c5
z8001: skip r13 frame setup when unused; pushl/popl pair save combine
Jul 13, 2026
e9c15ed
z8001: CSE fixed address/const args shared by consecutive calls
Jul 13, 2026
75ce7ac
z8001: collapse call-cleanup + re-push into an in-place store
Jul 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
589 changes: 589 additions & 0 deletions arch/z8001/code.c

Large diffs are not rendered by default.

763 changes: 763 additions & 0 deletions arch/z8001/local.c

Large diffs are not rendered by default.

3,083 changes: 3,083 additions & 0 deletions arch/z8001/local2.c

Large diffs are not rendered by default.

490 changes: 490 additions & 0 deletions arch/z8001/macdefs.h

Large diffs are not rendered by default.

201 changes: 201 additions & 0 deletions arch/z8001/order.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
* Copyright (c) 2026 Michal Pleban.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* pass2 instruction ordering for the Zilog Z8001 / Coherent target.
*
* On the Z8001, all pointer dereferences use a 32-bit segmented pair
* register (SBREG class) as the base address. Frame-relative access
* (autos, params) uses r13 (a plain word register) with the implicit DS.
*
* An OREG can be formed from:
* - A pair register (rr0..rr10): pointer-based indirect access
* - r13 (FPREG): frame-relative access (already an OREG from clocal)
* - PLUS/MINUS of a pair register and a small integer constant
*/

#include "pass2.h"
#include <string.h>

int canaddr(NODE *);

/*
* notoff: can we form an OREG with this offset?
* Z8001 indirect addressing supports a 16-bit signed displacement,
* so all offsets that fit in 16 bits are fine.
*/
int
notoff(TWORD t, int r, CONSZ off, char *cp)
{
/* All offsets fit in 16 bits for our purposes */
return off > 32767 || off < -32768;
}

/*
* offstar: prepare the argument of a UMUL (pointer dereference) so that
* it can be converted into an OREG by myormake().
*
* For Z8001, valid OREG bases are:
* - A pair register (SBREG): evaluate to INBREG
* - r13 (word reg): already handled as OREG by clocal
* - PLUS(pair_reg, ICON): evaluate left to INBREG
*/
void
offstar(NODE *p, int shape)
{
if (x2debug)
printf("offstar(%p)\n", p);

if (isreg(p))
return;

if (p->n_op == PLUS || p->n_op == MINUS) {
if (p->n_right->n_op == ICON) {
/* base + constant offset: evaluate base into a pair reg */
if (!isreg(p->n_left))
(void)geninsn(p->n_left, INBREG);
return;
}
}

/* General case: evaluate p into a pair register */
(void)geninsn(p, INBREG);
}

/*
* myormake: convert an already-evaluated UMUL child into an OREG.
*
* Called after offstar() has arranged the child. We look for the
* patterns that offstar() prepared.
*/
void
myormake(NODE *p)
{
NODE *q = p->n_left;

if (x2debug) {
printf("myormake(%p)\n", p);
fwalk(p, e2print, 0);
}

if (q->n_op == OREG)
return;

if ((q->n_op == PLUS || q->n_op == MINUS) &&
q->n_right->n_op == ICON &&
q->n_left->n_op == REG) {
/* PLUS/MINUS(reg, icon) → OREG with offset */
CONSZ off = getlval(q->n_right);
if (q->n_op == MINUS)
off = -off;
p->n_op = OREG;
setlval(p, off);
p->n_rval = regno(q->n_left);
tfree(q);
return;
}

if (q->n_op == REG) {
/* bare register → OREG with zero offset */
p->n_op = OREG;
setlval(p, 0);
p->n_rval = regno(q);
tfree(q);
return;
}
}

/*
* shumul: can a UMUL node be represented as a memory shape?
*
* Returns SROREG (will call offstar/myormake) or SRNOPE.
*/
int
shumul(NODE *p, int shape)
{
if (x2debug)
printf("shumul(%p)\n", p);

if (p->n_op == NAME && (shape & STARNM))
return SRDIR;

if (shape & SOREG)
return SROREG;

return SRNOPE;
}

/*
* setbin, setasg, setuni, setorder: instruction ordering hooks.
* For Z8001 we rely entirely on the table and don't need special handling.
*/
int
setbin(NODE *p)
{
return 0;
}

int
setasg(NODE *p, int cookie)
{
return 0;
}

int
setuni(NODE *p, int cookie)
{
return 0;
}

int
setorder(NODE *p)
{
return 0;
}

/*
* livecall: return registers that are live at a call instruction.
*
* On Z8001 with pure stack calling convention, no argument registers
* are live at the call site; the callee reads everything from the stack.
*/
int *
livecall(NODE *p)
{
static int r[] = { -1 };
return r;
}

/*
* acceptable: is this instruction acceptable for our target?
*
* Z8001 uses a simple flat instruction set with no variants that need
* filtering, so all table entries are acceptable.
*/
int
acceptable(struct optab *op)
{
return 1;
}
Loading