Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ba6eec0
aarch64: Add Darwin configuration.
hakanrw Nov 5, 2025
8eb0b9c
aarch64: Add architecture-dependent include path in Linux configuration.
hakanrw Feb 16, 2026
07c139c
aarch64: Fix ABI inaccuracies. Remove 32-bit ARMv7 assumptions.
hakanrw Jan 21, 2026
fde4f8b
aarch64: Remove macro definition which creates disrepancies across TUs.
hakanrw Jan 22, 2026
2abc716
aarch64: Fix problems in stack frame setup and parameter passing mech…
hakanrw Jan 21, 2026
d4709b2
aarch64: Implement address loading helpers.
hakanrw Feb 4, 2026
441895d
aarch64: Fix instruction table for 64-bits.
hakanrw Nov 24, 2025
6920108
aarch64: Fix assembly directive type names for initializing LONGLONG …
hakanrw Feb 15, 2026
55243c3
aarch64: Convert OREGs found in ADD/SUB instrs to AREGs.
hakanrw Jan 27, 2026
c29a02d
aarch64: Fix OREG conversion logic.
hakanrw Jan 28, 2026
7597af7
aarch64: Fix several patterns that block code generation.
hakanrw Feb 16, 2026
3c11ada
aarch64: Introduce literal pools for immediates that do not fit into …
hakanrw Jan 29, 2026
de54a7c
aarch64: Fix floating point extension. Implement FP SIMD instructions.
hakanrw Jan 22, 2026
6eda5c5
aarch64: Save permanent registers on the stack.
hakanrw Feb 3, 2026
3806348
aarch64: Remove inappropriate SCONV elision.
hakanrw Feb 3, 2026
157ac19
aarch64: Implement GOT/extern handling.
hakanrw Feb 4, 2026
2106254
aarch64: Prefix Mach-O symbols with underscore.
hakanrw Feb 11, 2026
54e4343
aarch64: Implement vararg passing for Mach-O ABI.
hakanrw Nov 24, 2025
b5fef33
aarch64: Fix section naming for Mach-O.
hakanrw Jan 19, 2026
3206b04
common: Implement IEEE-754 binary128 softfloat handler.
hakanrw Feb 4, 2026
41b5bd9
aarch64: Define basic LDOUBLE configuration for AAPCS64 and Darwin ABI.
hakanrw Feb 4, 2026
f3924ae
aarch64: Implement AAPCS64 calling convention for structs.
hakanrw Feb 7, 2026
85769ba
aarch64: Fix issue in strcvt().
hakanrw Feb 15, 2026
aa2bea0
ccom: Fix structure assignment ICE in simpleinit().
hakanrw Feb 15, 2026
2ee34d6
ccom: Preserve correct type when folding UMUL & ADDROF combination.
hakanrw Feb 16, 2026
97a7355
aarch64: Fix sym->sss getting obstructed by macro for LANG_C.
hakanrw Feb 21, 2026
0b5d859
aarch64: Add attribution.
hakanrw Jan 25, 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
873 changes: 463 additions & 410 deletions arch/aarch64/code.c

Large diffs are not rendered by default.

269 changes: 190 additions & 79 deletions arch/aarch64/local.c

Large diffs are not rendered by default.

529 changes: 357 additions & 172 deletions arch/aarch64/local2.c

Large diffs are not rendered by default.

182 changes: 150 additions & 32 deletions arch/aarch64/macdefs.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* $Id$ */
/*
* Copyright (c) 2025, 2026 Hakan Candar (hakan@candar.tr).
* Copyright (c) 2020 Puresoftware Ltd.
*
* Permission to use, copy, modify, and distribute this software for any
Expand Down Expand Up @@ -28,11 +29,15 @@
* Storage space requirements
*/
#define SZCHAR 8
#define SZBOOL 32
#define SZBOOL 8 /* XXX - investigate */
#define SZINT 32
#define SZFLOAT 32
#define SZDOUBLE 64
#ifndef MACHOABI
#define SZLDOUBLE 128
#else
#define SZLDOUBLE 64
#endif
#define SZLONG 64
#define SZSHORT 16
#define SZLONGLONG 64
Expand All @@ -42,17 +47,21 @@
* Alignment constraints
*/
#define ALCHAR 8
#define ALBOOL 32
#define ALBOOL 8
#define ALINT 32
#define ALFLOAT 32
#define ALDOUBLE 32
#define ALLDOUBLE 32
#define ALLONG 32
#define ALLONGLONG 32
#define ALDOUBLE 64
#ifndef MACHOABI
#define ALLDOUBLE 128
#else
#define ALLDOUBLE 64
#endif
#define ALLONG 64
#define ALLONGLONG 64
#define ALSHORT 16
#define ALPOINT 32
#define ALPOINT 64
#define ALSTRUCT 32
#define ALSTACK 32
#define ALSTACK 128

/*
* Min/max values.
Expand All @@ -63,7 +72,7 @@
#define MIN_SHORT -32768
#define MAX_SHORT 32767
#define MAX_USHORT 65535
#define MIN_INT -1
#define MIN_INT (-0x7fffffff-1)
#define MAX_INT 0x7fffffff
#define MAX_UNSIGNED 0xffffffff
#define MIN_LONG 0x8000000000000000L
Expand All @@ -73,7 +82,7 @@
#define MAX_LONGLONG 0x7fffffffffffffffLL
#define MAX_ULONGLONG 0xffffffffffffffffULL

#define BOOL_TYPE INT /* what used to store _Bool */
#define BOOL_TYPE UCHAR /* what used to store _Bool */

/*
* Use large-enough types.
Expand All @@ -96,8 +105,7 @@ typedef long long OFFSZ;
#define STOFARG(p)
#define STOSTARG(p)

#define szty(t) (((t) == DOUBLE || (t) == LDOUBLE || \
(t) == LONG || (t) == ULONG || (t) == LONGLONG || (t) == ULONGLONG) ? 2 : 1)
#define szty(t) (t < LONG || t == FLOAT ? 1 : t == LDOUBLE ? 4 : 2)

#define R0 0
#define R1 1
Expand Down Expand Up @@ -137,29 +145,133 @@ typedef long long OFFSZ;
#define SP R31
#define LR R30

#define V0 32
#define V1 33
#define V2 34
#define V3 35
#define V4 36
#define V5 37
#define V6 38
#define V7 39
#define V8 40
#define V9 41
#define V10 42
#define V11 43
#define V12 44
#define V13 45
#define V14 46
#define V15 47
#define V16 48
#define V17 49
#define V18 50
#define V19 51
#define V20 52
#define V21 53
#define V22 54
#define V23 55
#define V24 56
#define V25 57
#define V26 58
#define V27 59
#define V28 60
#define V29 61
#define V30 62
#define V31 63

#define NUMCLASS 3
#define MAXREGS 34
#define MAXREGS 64

#define RSTATUS \
SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, \
SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, \
SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, \
0, 0, 0, 0, 0, \
SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG, SBREG, \
SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, \
SCREG, SCREG, SCREG, SCREG, \
SCREG, SCREG, SCREG, SCREG, \
/* x0 */ SAREG|TEMPREG, \
/* x1 */ SAREG|TEMPREG, \
/* x2 */ SAREG|TEMPREG, \
/* x3 */ SAREG|TEMPREG, \
/* x4 */ SAREG|TEMPREG, \
/* x5 */ SAREG|TEMPREG, \
/* x6 */ SAREG|TEMPREG, \
/* x7 */ SAREG|TEMPREG, \
/* x8 */ SAREG|TEMPREG, \
/* x9 */ SAREG|TEMPREG, \
/* x10 */ SAREG|TEMPREG, \
/* x11 */ SAREG|TEMPREG, \
/* x12 */ SAREG|TEMPREG, \
/* x13 */ SAREG|TEMPREG, \
/* x14 */ SAREG|TEMPREG, \
/* x15 */ SAREG|TEMPREG, \
/* x16 */ 0, /* IP0 scratch (not allocatable) */ \
/* x17 */ 0, /* IP1 scratch */ \
/* x18 */ 0, /* platform register */ \
/* x19 */ SAREG|PERMREG, \
/* x20 */ SAREG|PERMREG, \
/* x21 */ SAREG|PERMREG, \
/* x22 */ SAREG|PERMREG, \
/* x23 */ SAREG|PERMREG, \
/* x24 */ SAREG|PERMREG, \
/* x25 */ SAREG|PERMREG, \
/* x26 */ SAREG|PERMREG, \
/* x27 */ SAREG|PERMREG, \
/* x28 */ SAREG|PERMREG, \
/* x29 */ 0, /* FP (frame pointer) */ \
/* x30 */ 0, /* LR */ \
/* x31 */ 0, /* SP/WZR */ \
\
/* class B empty for now */ \
\
/* v0 */ SCREG|TEMPREG, \
/* v1 */ SCREG|TEMPREG, \
/* v2 */ SCREG|TEMPREG, \
/* v3 */ SCREG|TEMPREG, \
/* v4 */ SCREG|TEMPREG, \
/* v5 */ SCREG|TEMPREG, \
/* v6 */ SCREG|TEMPREG, \
/* v7 */ SCREG|TEMPREG, \
/* v8 */ SCREG|PERMREG, /* callee-saved */ \
/* v9 */ SCREG|PERMREG, /* callee-saved */ \
/* v10 */ SCREG|PERMREG, /* callee-saved */ \
/* v11 */ SCREG|PERMREG, /* callee-saved */ \
/* v12 */ SCREG|PERMREG, /* callee-saved */ \
/* v13 */ SCREG|PERMREG, /* callee-saved */ \
/* v14 */ SCREG|PERMREG, /* callee-saved */ \
/* v15 */ SCREG|PERMREG, /* callee-saved */ \
/* v16 */ SCREG|TEMPREG, \
/* v17 */ SCREG|TEMPREG, \
/* v18 */ SCREG|TEMPREG, \
/* v19 */ SCREG|TEMPREG, \
/* v20 */ SCREG|TEMPREG, \
/* v21 */ SCREG|TEMPREG, \
/* v22 */ SCREG|TEMPREG, \
/* v23 */ SCREG|TEMPREG, \
/* v24 */ SCREG|TEMPREG, \
/* v25 */ SCREG|TEMPREG, \
/* v26 */ SCREG|TEMPREG, \
/* v27 */ SCREG|TEMPREG, \
/* v28 */ SCREG|TEMPREG, \
/* v29 */ SCREG|TEMPREG, \
/* v30 */ SCREG|TEMPREG, \
/* v31 */ 0 /* unusable due to class size limit */


/* no overlapping registers at all */
#define ROVERLAP \
{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
{ -1 }, { -1 }, { -1 }, { -1 }, \
\
/* class B empty for now */ \
\
{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
{ -1 }, { -1 }, { -1 }, { -1 }


#define STACK_DOWN /* stack grows negatively for temporaries */

#define ARGINIT (16*8) /* # bits above fp where arguments start */
#define AUTOINIT (32*8) /* # bits above fp where automatics start */
#define AUTOINIT 0 /* # bits above fp where automatics start */

#undef FIELDOPS /* no bit-field instructions */
#define TARGET_ENDIAN TARGET_LE
Expand All @@ -171,7 +283,7 @@ typedef long long OFFSZ;
/* Return a register class based on the type of the node */
#define PCLASS(p) (1 << gclass((p)->n_type))

#define GCLASS(x) (x < 16 ? CLASSA : x < 26 ? CLASSB : CLASSC)
#define GCLASS(x) (x < 32 ? CLASSA : CLASSC )
#define DECRA(x,y) (((x) >> (y*6)) & 63) /* decode encoded regs */
#define ENCRD(x) (x) /* Encode dest reg in n_reg */
#define ENCRA1(x) ((x) << 6) /* A1 */
Expand All @@ -183,15 +295,15 @@ int COLORMAP(int c, int *r);
int retreg(int ty);
int features(int f);

/*
* aarch64-specific symbol table flags.
*/
#define ATTR_P1_TARGET ATTR_AARCH64_BEENHERE

#define FEATURE_BIGENDIAN 0x00010000
#define FEATURE_HALFWORDS 0x00020000 /* ldrsh/ldrh, ldrsb */
#define FEATURE_EXTEND 0x00040000 /* sxth, sxtb, uxth, uxtb */
#define FEATURE_MUL 0x00080000
#define FEATURE_MULL 0x00100000
#define FEATURE_DIV 0x00200000
#define FEATURE_FPA 0x10000000
#define FEATURE_VFP 0x20000000
#define FEATURE_HARDFLOAT (FEATURE_FPA|FEATURE_VFP)
#define FEATURE_FPSIMD 0x10000000
#define FEATURE_HARDFLOAT (FEATURE_FPSIMD)

#undef NODE
#ifdef LANG_CXX
Expand All @@ -208,12 +320,18 @@ NODE *arm_builtin_va_copy(const struct bitable *bt, NODE *a);
#undef NODE

#define COM "\t// "
#define NARGREGS 4
#define NARGREGS 8

/* floating point definitions */
#define USE_IEEEFP_32
#define FLT_PREFIX IEEEFP_32
#define USE_IEEEFP_64
#define DBL_PREFIX IEEEFP_64
#ifndef MACHOABI
#define USE_IEEEFP_128
#define LDBL_PREFIX IEEEFP_128
#define DEFAULT_FPI_DEFS { &fpi_binary32, &fpi_binary64, &fpi_binary128 }
#else
#define LDBL_PREFIX IEEEFP_64
#define DEFAULT_FPI_DEFS { &fpi_binary32, &fpi_binary64, &fpi_binary64 }
#endif
34 changes: 19 additions & 15 deletions arch/aarch64/order.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ int
notoff(TWORD ty, int r, CONSZ off, char *cp)
{
if (cp && cp[0]) return 1;
if (DEUNSIGN(ty) == INT || ty == UCHAR)
return !(off < 4096 && off > -4096);
else
return !(off < 256 && off > -256);
return !(off < 256 && off >= -256);
}

/*
Expand All @@ -52,10 +49,23 @@ offstar(NODE *p, int shape)

r = p->n_right;
if( p->n_op == PLUS || p->n_op == MINUS ){
if (r->n_op == OREG || r->n_op == NAME) {
/* OREG/NAMEs in PLUS/MINUS instructions
* should be moved into AREG first.
* one case is runtime array indexing i.e. arr[idx].
*/
r = mkbinode(SCONV, r, NULL, LONGLONG);
p->n_right = r;
(void)geninsn(p->n_right, INAREG);
if (isreg(p->n_left) == 0)
(void)geninsn(p->n_left, INAREG);
(void)geninsn(p, INAREG);
return;
}
if( r->n_op == ICON ){
if (isreg(p->n_left) == 0)
(void)geninsn(p->n_left, INAREG);
/* Converted in ormake() */
(void)geninsn(p, INAREG);
return;
}
/* usually for arraying indexing: */
Expand All @@ -65,15 +75,15 @@ offstar(NODE *p, int shape)
(void)geninsn(p->n_left, INAREG);
if (isreg(r->n_left) == 0)
(void)geninsn(r->n_left, INAREG);
/* Converted in ormake() */
return;
}
}
(void)geninsn(p, INAREG);
}

/*
* Unable to convert to OREG (notoff() returned failure). Output
* suitable instructions to replace OREG.
* Do the actual conversion of offstar-found OREGs into real OREGs.
*/
void
myormake(NODE *q)
Expand All @@ -89,13 +99,7 @@ myormake(NODE *q)
* This handles failed OREGs conversions, due to the offset
* being too large for an OREG.
*/
if ((p->n_op == PLUS || p->n_op == MINUS) && p->n_right->n_op == ICON) {
if (isreg(p->n_left) == 0)
(void)geninsn(p->n_left, INAREG);
if (isreg(p->n_right) == 0)
(void)geninsn(p->n_right, INAREG);
(void)geninsn(p, INAREG);
} else if (p->n_op == REG) {
if (p->n_op == REG) {
q->n_op = OREG;
setlval(q, getlval(p));
q->n_rval = p->n_rval;
Expand Down Expand Up @@ -303,7 +307,7 @@ setorder(NODE *p)
int *
livecall(NODE *p)
{
static int r[] = { R3, R2, R1, R0, -1 };
static int r[] = { R3, R2, R1, R0, -1 }; /* XXX - investigate */
int num = 1;

if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
Expand Down
Loading