Skip to content

Commit daf59e4

Browse files
[binutils] add binutils support
1 parent acbc64e commit daf59e4

File tree

519 files changed

+7757
-6317
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

519 files changed

+7757
-6317
lines changed

.github/workflows/branch.yml

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ env:
1111
AUTOTESTER_ROM: ${{github.workspace}}/secrets/83pce_515_530.rom
1212
CEDEV: ${{github.workspace}}/CEdev
1313
CEDEV_BIN: ${{github.workspace}}/CEdev/bin
14+
CEDEV_BINUTILS_BIN: ${{github.workspace}}/CEdev/binutils/bin
1415
CEDEV_EXAMPLES: ${{github.workspace}}/CEdev/examples
1516
CEDEV_TEST: ${{github.workspace}}/toolchain/test
1617
CEMU_PATH: ${{github.workspace}}/CEmu
@@ -33,24 +34,30 @@ jobs:
3334
fasmg: /source/macos/x64/fasmg
3435
arch-suffix: "-intel"
3536
ez80-bins-suffix: macOS_intel
37+
binutils-suffix: macos_intel
3638
- runs-on: macos-14
3739
fasmg: /source/macos/x64/fasmg
3840
arch-suffix: "-arm"
3941
ez80-bins-suffix: macOS_arm
42+
binutils-suffix: macos_arm
4043
- runs-on: windows-latest
4144
fasmg: /fasmg.exe
4245
ez80-bins-suffix: windows
46+
binutils-suffix: windows
4347
env: "env:"
4448
exe: .exe
4549
nul: nul
4650
ldflags: LDFLAGS="-static-libgcc -static-libstdc++ -static"
4751
- runs-on: ubuntu-22.04
4852
ez80-bins-suffix: ubuntu
53+
binutils-suffix: ubuntu
4954
fasmg: /fasmg.x64
5055
runs-on: ${{matrix.runs-on}}
5156
steps:
5257
- name: Prepare Build Environment
53-
run: cmake -E echo >> $${{matrix.env}}GITHUB_PATH ${{env.CEDEV_BIN}}
58+
run: |
59+
cmake -E echo >> $${{matrix.env}}GITHUB_PATH ${{env.CEDEV_BIN}}
60+
cmake -E echo >> $${{matrix.env}}GITHUB_PATH ${{env.CEDEV_BINUTILS_BIN}}
5461
5562
- name: Download ez80-clang and ez80-link
5663
id: ez80-bins
@@ -63,6 +70,17 @@ jobs:
6370
pathSource: ${{steps.ez80-bins.outputs.file-path}}
6471
pathTarget: ${{env.CEDEV_BIN}}
6572

73+
- name: Download binutils
74+
id: binutils
75+
uses: carlosperate/[email protected]
76+
with:
77+
file-url: https://github.com/CE-Programming/binutils-gdb/releases/download/nightly/binutils_${{matrix.binutils-suffix}}_nightly.zip
78+
- name: Extract binutils
79+
uses: DuckSoft/[email protected]
80+
with:
81+
pathSource: ${{steps.binutils.outputs.file-path}}
82+
pathTarget: ${{env.CEDEV}}
83+
6684
- name: Add fasmg website to /etc/hosts since DNS seems to be broken
6785
if: runner.os == 'macOS'
6886
run: |
@@ -109,7 +127,9 @@ jobs:
109127

110128
- name: Make Binaries Executable
111129
if: runner.os != 'Windows'
112-
run: chmod +x ${{env.CEDEV_BIN}}/*
130+
run: |
131+
chmod +x ${{env.CEDEV_BIN}}/*
132+
chmod +x ${{env.CEDEV_BINUTILS_BIN}}/*
113133
- name: Test Build Dependencies
114134
run: |
115135
ez80-clang --version
@@ -135,9 +155,14 @@ jobs:
135155
PREFIX: ${{github.workspace}}
136156
run: make -j4 -C ${{env.TOOLCHAIN_PATH}} install V=1 DESTDIR=${{github.workspace}}
137157

158+
- name: Remove Fasmg
159+
run: cmake -E rm -f ${{env.CEDEV_BIN}}/fasmg${{matrix.exe}}
160+
138161
- name: Make Binaries Executable
139162
if: runner.os != 'Windows'
140-
run: chmod +x ${{env.CEDEV_BIN}}/*
163+
run: |
164+
chmod +x ${{env.CEDEV_BIN}}/*
165+
chmod +x ${{env.CEDEV_BINUTILS_BIN}}/*
141166
142167
- name: Build Test Graphics
143168
run: make -j4 -C ${{env.CEDEV_TEST}} COMPRESSED=${{matrix.compressed}} V=1 gfx

.github/workflows/make.yml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ env:
1313
AUTOTESTER_ROM: ${{github.workspace}}/secrets/83pce_515_530.rom
1414
CEDEV: ${{github.workspace}}/CEdev
1515
CEDEV_BIN: ${{github.workspace}}/CEdev/bin
16+
CEDEV_BINUTILS_BIN: ${{github.workspace}}/CEdev/binutils/bin
1617
CEDEV_EXAMPLES: ${{github.workspace}}/CEdev/examples
1718
CEDEV_TEST: ${{github.workspace}}/toolchain/test
1819
CEMU_PATH: ${{github.workspace}}/CEmu
@@ -33,28 +34,34 @@ jobs:
3334
fasmg: /source/macos/x64/fasmg
3435
arch-suffix: "-intel"
3536
ez80-bins-suffix: macOS_intel
37+
binutils-suffix: macos_intel
3638
install-output-ext: "dmg"
3739
- runs-on: macos-14
3840
fasmg: /source/macos/x64/fasmg
3941
arch-suffix: "-arm"
4042
ez80-bins-suffix: macOS_arm
43+
binutils-suffix: macos_arm
4144
install-output-ext: "dmg"
4245
- runs-on: windows-latest
4346
fasmg: /fasmg.exe
4447
ez80-bins-suffix: windows
48+
binutils-suffix: windows
4549
env: "env:"
4650
exe: .exe
4751
nul: nul
4852
ldflags: LDFLAGS="-static-libgcc -static-libstdc++ -static"
4953
install-output-ext: "zip"
5054
- runs-on: ubuntu-22.04
5155
ez80-bins-suffix: ubuntu
56+
binutils-suffix: ubuntu
5257
fasmg: /fasmg.x64
5358
install-output-ext: "tar.gz"
5459
runs-on: ${{matrix.runs-on}}
5560
steps:
5661
- name: Prepare Build Environment
57-
run: cmake -E echo >> $${{matrix.env}}GITHUB_PATH ${{env.CEDEV_BIN}}
62+
run: |
63+
cmake -E echo >> $${{matrix.env}}GITHUB_PATH ${{env.CEDEV_BIN}}
64+
cmake -E echo >> $${{matrix.env}}GITHUB_PATH ${{env.CEDEV_BINUTILS_BIN}}
5865
5966
- name: Download ez80-clang and ez80-link
6067
id: ez80-bins
@@ -67,6 +74,17 @@ jobs:
6774
pathSource: ${{steps.ez80-bins.outputs.file-path}}
6875
pathTarget: ${{env.CEDEV_BIN}}
6976

77+
- name: Download binutils
78+
id: binutils
79+
uses: carlosperate/[email protected]
80+
with:
81+
file-url: https://github.com/CE-Programming/binutils-gdb/releases/download/nightly/binutils_${{matrix.binutils-suffix}}_nightly.zip
82+
- name: Extract binutils
83+
uses: DuckSoft/[email protected]
84+
with:
85+
pathSource: ${{steps.binutils.outputs.file-path}}
86+
pathTarget: ${{env.CEDEV}}
87+
7088
- name: Add fasmg website to /etc/hosts since DNS seems to be broken
7189
if: runner.os == 'macOS'
7290
run: |
@@ -139,9 +157,14 @@ jobs:
139157
PREFIX: ${{github.workspace}}
140158
run: make -j4 -C ${{env.TOOLCHAIN_PATH}} install V=1 DESTDIR=${{github.workspace}}
141159

160+
- name: Remove Fasmg
161+
run: cmake -E rm -f ${{env.CEDEV_BIN}}/fasmg${{matrix.exe}}
162+
142163
- name: Make Binaries Executable
143164
if: runner.os != 'Windows'
144-
run: chmod +x ${{env.CEDEV_BIN}}/*
165+
run: |
166+
chmod +x ${{env.CEDEV_BIN}}/*
167+
chmod +x ${{env.CEDEV_BINUTILS_BIN}}/*
145168
146169
- name: "[macOS] CodeSign Toolchain binaries"
147170
if: runner.os == 'macOS' && github.repository == 'CE-Programming/toolchain' # don't run on forks, since they don't have secrets
@@ -461,4 +484,3 @@ jobs:
461484
token: ${{ secrets.CI_PAT_CLIBS_NIGHTLTY }}
462485
repository: CE-Programming/libraries
463486
event-type: ci-clibs-nightly
464-

docs/headers/ti/sprintf.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ The truncating behavior of C99 `snprintf` can be replicated with `boot_asprintf`
7272
7373
printf and fprintf
7474
------------------
75-
`printf` and `fprintf` can be replicated by using `fputs`
75+
76+
`printf` and `fprintf` can be replicated by using `fputs`.
7677

7778
.. code-block:: c
7879

docs/static/asm.rst

Lines changed: 43 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,50 @@
11
.. _asm:
22

3-
Assembly Routines
4-
=================
3+
Assembly Files
4+
==============
55

6-
Assembly routines can be linked into a C/C++ program by putting them into the same **src** directory that your C/C++ sources are in, but with an **.asm** extension.
7-
These can be placed in any subdirectory of **src** just like C/C++ sources.
6+
Assembly files can be linked into a C/C++ program by putting them into the same **src** directory that your C/C++ sources are in.
7+
Use a **.S** extension if you want the compiler's preprocessor to run on the file first, or use a **.s** extension if the assembly file does not need to be preprocessed.
88

9-
Assembly Files
10-
--------------
9+
The use of inline assembly is supported, but highly discouraged as future changes to the compiler may render the inline assembly incompatible, and it reduces the readablity of the code.
10+
11+
Assembler
12+
---------
1113

12-
.. _asm-consts:
14+
The CE Toolchain uses the GNU Assembler (GAS) to assemble source files.
15+
Historically the fasmg assembler was used, but is no longer supported to allow for better cross-platform support and linking performance.
1316

14-
Constants
15-
^^^^^^^^^
17+
Documentation for the GNU Assembler: https://www.sourceware.org/binutils/docs/as/index.html
1618

17-
The top of the file is a good place defining constants or including other files that define constants.
18-
These will be availabe throughout the rest of the file, but not in other files.
19-
You can define a constant by saying :code:`my_constant := 42`.
20-
You can include common constants in multiple files by defining them in a file named, say, **file.inc** and putting :code:`include 'file.inc'` in every file that needs them.
21-
You should not generally put any labels, code, or data here.
22-
If you try to reference a label defined here, you will get an :code:`Error: variable term used where not expected.` linker error which means you are trying to resolve an address that doesn't belong to any section.
23-
See :ref:`asm-section` to fix this problem.
19+
Specific Z80/ez80 directives: https://www.sourceware.org/binutils/docs/as/Z80-Directives.html
2420

2521
.. _asm-assume:
2622

2723
Assume
2824
^^^^^^
2925

30-
You should add a :code:`assume adl=1` before trying to emit any code, which ensures that you get 24-bit eZ80 instructions.
31-
If you end an assembly file with :code:`assume adl=0` (which is the eZ80's 16-bit Z80 compatibility mode), it will propogate to another random assembly file.
32-
All toolchain and compiler-generated sources make sure to reset the mode at the top of the file and end the file in the same mode, but if one of your sources end in Z80 mode, then any other one of your sources might begin in Z80 mode, so it is safer to put the :code:`assume` line in every file.
26+
You should add a :code:`.assume ADL=1` before trying to emit any code, which ensures that you get 24-bit eZ80 instructions.
3327

3428
.. _asm-section:
3529

36-
Section
37-
^^^^^^^
30+
Sections
31+
^^^^^^^^
3832

39-
Now that we are in the correct mode, we need to tell the linker where to put things.
40-
We use :code:`section .text` for code, :code:`section .data` for variables, and :code:`section .rodata` for constant data.
41-
Currently these are all placed in RAM, so which section you choose to switch to is much less important than how often you switch sections, even if you are switching to the same section you are already in.
42-
This is because every time you start a new, or restart the same, section, the linker gets a new opportunity to delete a block of dead code/data.
33+
The CE Toolchain uses :code:`.section .text` for code, :code:`.section .data` for variables, and :code:`.section .rodata` for constant data.
34+
Every time you start a new section (such as :code:`.section .text.function`), the linker has an opportunity to delete a block of dead code/data.
4335
Because of this, the correct time to switch sections is usually every time you start a new function or variable.
44-
You should not let execution fall off the end of a block because you won't know if that block will be included or deleted from the output, however you can if you say :code:`require _symbol` of some public or private symbol defined in the next section to ensure that if the current block is included, then that will force the next block to also be included.
45-
To define a symbol in a block that can be referenced from other blocks, you should do :code:`private _symbol` or :code:`public _symbol` right before its definition.
46-
If it is private then it is only able to be referenced from the same file and no :ref:`extern <asm-extern>` should be used.
47-
If it is public then it can be referenced within the same file without :ref:`extern <asm-extern>` just like private symbols, but public symbols can also be referenced from other files and even C/C++!
48-
The public assembly symbol named :code:`_symbol` is accessible in C by the global name :code:`symbol`, assuming it is properly declared, with your asm symbol acting as the definition.
36+
To define a symbol in a block that can be referenced from other blocks, you should do :code:`.local _symbol` or :code:`.global _symbol` right before its definition.
37+
If it is local then it is only able to be referenced from the same file and no :ref:`.extern <asm-extern>` should be used.
38+
If it is global then it can be referenced within the same file without :ref:`.extern <asm-extern>` just like local symbols, but global symbols can also be referenced from other files and even C/C++!
39+
The gllobal assembly symbol named :code:`_symbol` is accessible in C by the global name :code:`symbol` (note the leading underscore), assuming it is properly declared, with your asm symbol acting as the definition.
4940

5041
.. _asm-extern:
5142

5243
Extern
5344
^^^^^^
5445

55-
At the end of the file is a good place to list every external symbol that you might depend on like :code:`extern _symbol`.
56-
This includes both public symbols defined in another assembly file and global symbols from C, prefixed with an underscore like usual.
57-
Lastly, you should not let execution fall off the end of a file because the next file that gets assembled is unpredictable and you could end up anywhere!
46+
At the end of the file is a good place to list every external symbol that you might depend on like :code:`.extern _symbol`.
47+
This includes both global symbols defined in another assembly file and global symbols from C, prefixed with an underscore.
5848
Block ordering can only be relied on within a single file, and only for blocks belonging to the same section.
5949

6050
Linking ASM routines to C/C++
@@ -69,17 +59,18 @@ Below is an example C prototype followed by the assembly implementation:
6959

7060
.. code-block:: c
7161
72-
void asm_func(int arg);
62+
void asm_func(int argument);
7363
7464
:code:`asm_func.asm`
7565

7666
.. code-block::
7767
78-
assume adl=1
79-
80-
section .text
81-
82-
public _asm_func
68+
.assume adl=1
69+
70+
.section .text._asm_func
71+
.global _asm_func
72+
.type _asm_func, @function
73+
8374
_asm_func:
8475
pop hl
8576
pop de
@@ -91,33 +82,29 @@ Below is an example C prototype followed by the assembly implementation:
9182
pop de
9283
9384
ret
94-
95-
extern _external_func
85+
86+
.extern _external_func
9687
9788
:code:`asm_func.c`
9889

9990
.. code-block::
10091
101-
int external_func(int arg) {
92+
int external_func(int arg)
93+
{
10294
printf("external_func called with %d\n", arg);
10395
return 4321;
10496
}
10597
106-
void test() {
98+
void test(void)
99+
{
107100
int arg = 1234;
108101
printf("calling asm_func with %d\n", arg);
109102
int ret = asm_func(arg);
110103
printf("asm_func returned %d\n", ret);
111104
}
112105
113-
Preserve
114-
^^^^^^^^
115-
116-
Assembly routines must preserve the :code:`IX` and :code:`SP` registers.
117-
All other registers are free for use.
118-
119-
Arguments
120-
^^^^^^^^^
106+
ABI Arguments
107+
^^^^^^^^^^^^^
121108

122109
Arguments are pushed from last to first corresponding to the C prototype.
123110
In eZ80, 3 bytes are always pushed to the stack regardless of the actual size.
@@ -126,6 +113,9 @@ For example, if a *short* type is used, the upper byte of the value pushed on th
126113
This table lists the locations relative to *sp* from within the called funciton.
127114
Note that :code:`sp + [0,2]` contains the return address.
128115

116+
Assembly routines must preserve the :code:`IX` and :code:`SP` registers.
117+
All other registers are free for use.
118+
129119
+-------------+------------+----------------------+
130120
| C/C++ Type | Size | Stack Location |
131121
+=============+============+======================+
@@ -150,8 +140,8 @@ Note that :code:`sp + [0,2]` contains the return address.
150140
| pointer | 3 bytes | sp + [3,5] |
151141
+-------------+------------+----------------------+
152142

153-
Returns
154-
^^^^^^^
143+
ABI Returns
144+
^^^^^^^^^^^
155145

156146
This table lists which registers are used for return values from a function.
157147
The type's sign does not affect the registers used, but may affect the value returned.

docs/static/contributing.rst

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,16 @@ Building the CE Toolchain
2121
Linux and macOS
2222
~~~~~~~~~~~~~~~
2323

24-
Get the `ez80 LLVM compiler <https://github.com/jacobly0/llvm-project/wiki>`_.
24+
It is usually easier to download a toolchain release which already contains the needed binaries for compiling/assembling if you are just making code modifications to the toolchain.
25+
If you need to do everything from scratch though, the steps are below.
26+
27+
Download the prebuilt `ez80 LLVM compiler <https://github.com/CE-Programming/llvm-project/releases/tag/nightly>`_.
2528
Make sure that ``ez80-clang`` and ``ez80-link`` are reachable by the system's PATH environment variable.
2629

27-
Get the `fasmg assembler <https://flatassembler.net/download.php>`_.
30+
Download the prebuilt `ez80 GNU binutils <https://github.com/CE-Programming/binutils-gdb/releases/tag/nightly>`_
31+
Make sure that ``bin`` directory is reachable by the system's PATH environment variable.
32+
33+
Download the `fasmg assembler <https://flatassembler.net/download.php>`_.
2834
The download is located near the bottom of the page.
2935
Extract the ``fasmg.x64`` executable to the same location as the compiler.
3036
Rename it to just ``fasmg``.
@@ -51,15 +57,21 @@ This is configurable with :code:`make install PREFIX=[LOCATION]`
5157
Windows
5258
~~~~~~~
5359

60+
It is usually easier to download a toolchain release which already contains the needed binaries for compiling/assembling if you are just making code modifications to the toolchain.
61+
If you need to do everything from scratch though, the steps are below.
62+
5463
Get `MSYS2 <https://www.msys2.org/>`_ and use the `MinGW64` environment.
5564

5665
The only required pacakge is `mingw-w64-x86_64-toolchain <https://packages.msys2.org/groups/mingw-w64-x86_64-toolchain>`_.
5766
Make sure the ``C:\msys64\mingw64\bin`` directory is in the system's PATH environment variable.
5867

59-
Get the `ez80 LLVM compiler <https://github.com/jacobly0/llvm-project/wiki>`_.
68+
Download the prebuilt `ez80 LLVM compiler <https://github.com/CE-Programming/llvm-project/releases/tag/nightly>`_.
6069
Make sure that ``ez80-clang.exe`` and ``ez80-link.exe`` are reachable by the system's PATH environment variable.
6170

62-
Get the `fasmg assembler <https://flatassembler.net/download.php>`_.
71+
Download the prebuilt `ez80 GNU binutils <https://github.com/CE-Programming/binutils-gdb/releases/tag/nightly>`_
72+
Make sure that ``bin`` directory is reachable by the system's PATH environment variable.
73+
74+
Download the `fasmg assembler <https://flatassembler.net/download.php>`_.
6375
The download is located near the bottom of the page.
6476
Extract the ``fasmg.exe`` executable to the same location as the compiler.
6577

0 commit comments

Comments
 (0)