Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot compile assembly to the z80 binary #2

Closed
newchief opened this issue Mar 3, 2014 · 4 comments
Closed

cannot compile assembly to the z80 binary #2

newchief opened this issue Mar 3, 2014 · 4 comments

Comments

@newchief
Copy link

newchief commented Mar 3, 2014

I'd like to ask you, what assembler are you using to build final binary from z80 assembly files outputed by llc.
I tried sdasz80 from sdcc package, it throws a lot of error lines:

bash-3.2$ llc -march=z80 -O0 test.ll
bash-3.2$ sdasz80 test.bin test.s
test.s:1: Error: missing or improper operators, terminators, or delimiters
test.s:2: Error: missing or improper operators, terminators, or delimiters
test.s:4: Error: .org in REL area or directive / mnemonic error
test.s:5: Error: missing or improper operators, terminators, or delimiters
test.s:6: Error: missing or improper operators, terminators, or delimiters
test.s:9: Error: machine specific addressing or addressing mode error
test.s:14: Error: missing or improper operators, terminators, or delimiters
.....and so on

Also I tried z80asm:

bash-3.2$ z80asm -v -o test.bin test.s
Assembling....
test.s:1: error: command or comment expected (was .file "test.ll" )
test.s:2: error: command or comment expected (was .text )
test.s:3: error: command or comment expected (was .globl fun )
test.s:4: error: command or comment expected (was .type fun,@function )
test.s:5: error: command or comment expected (was # @fun )
test.s:6: error: command or comment expected (was # BB#0: )
test.s:28: error: command or comment expected (was # =>This Inner Loop Header: Depth=1 )
test.s:38: error: command or comment expected (was # in Loop: Header=BB0_1 Depth=1 )
test.s:50: error: command or comment expected (was # kill: BC )
...
*** 54 errors found ***

Finally, none of them produced test.bin file.

Unfortunately, llc also can't build binary objects:

bash-3.2$ llc -march=z80 -filetype=obj -O0 test.ll
0 llc 0x0000000100e3f084 llvm::sys::PrintStackTrace(sFILE) + 38
1 llc 0x0000000100e3f2b3 PrintStackTraceSignalHandler(void
) + 27
2 llc 0x0000000100e3f7bf SignalHandler(int) + 254
3 libSystem.B.dylib 0x00007fff83db21ba sigtramp + 26
4 libSystem.B.dylib 0x0000000102819600 sigtramp + 2124837984
5 llc 0x0000000100932ae7 llvm::LLVMTargetMachine::addPassesToEmitFile(llvm::PassManagerBase&, llvm::formatted_raw_ostream&, llvm::TargetMachine::CodeGenFileType, bool, void const
, void const
) + 1457
6 llc 0x00000001000347e0 compileModule(char**, llvm::LLVMContext&) + 3454
7 llc 0x00000001000349e3 main + 199
8 llc 0x0000000100033574 start + 52
9 llc 0x0000000000000005 start + 4294757061
Stack dump:
0. Program arguments: llc -march=z80 -filetype=obj -O0 test.ll
Segmentation fault

@earl1k
Copy link
Owner

earl1k commented Mar 3, 2014

LLVM z80 can't generate binary output, yet. This project is developed like z80 clang and not ready for using.

@earl1k earl1k closed this as completed Mar 3, 2014
@earl1k earl1k reopened this Mar 3, 2014
@earl1k earl1k closed this as completed Mar 8, 2014
@newchief
Copy link
Author

I've finally found some time to look closer at the problem. First I must apologize, since I didn't check the most obvious thing: binutils with its GNU assembler can be built for targeting Z80 CPU.
Binutils should be built with '--target=z80-unknown-coff' configure option, then LLVM and Clang should be built with '-DLLVM_DEFAULT_TARGET_TRIPLE=z80-unknown-coff' CMake option.
Compiling with z80-unknown-coff-as command produces far less error messages than with any other z80 assembler. These errors can be corrected with sed command. Whole procedure is following:

clang -target z80-unknown-coff -Wall -S -emit-llvm -c test.c <=== this produces test.ll
llc -mtriple z80-unknown-coff test.ll <=== this produces test.s
cat test.s | sed -e 's/.type/#/' -e 's/.size/#/' -e 's/#.*$//' | z80-unknown-coff-as -o test.o
z80-unknown-coff-ld -o test.bin -Ttext=0x8000 -Tdata=0x9000 test.o <=== code will start at the address 0x8000 == 32768
file2tap test.tap test.bin 3 32768 <=== '3' means 'Bytes:'

It turns out that z80-unknown-coff-ld produces binary that can be freely executed on typical Z80 machine like ZX Spectrum.
Now this test.tap file produced by file2tap utility can be loaded in Fuse emulator:
CLEAR 32767
LOAD "test.bin" CODE
RANDOMIZE USR 32768

What 'sed' command does is:

  1. it turns all .type and .size directives into comments by replacing all occurrences of .type or .size into a '#'
  2. GNU as does not understand the way llc emits numeric constants. For example, code like this:
#include <stdint.h>

uint16_t array[] = { 1, 2, 3, 4 };

...will turn into this:

    .type   array,@object           # @array
    .globl  array
    .align  2
array:
    .short  1                       # 0x1
    .short  2                       # 0x2
    .short  3                       # 0x3
    .short  4                       # 0x4
    .size   array, 8

all these '# 0x...' need to be removed. So with -e 's/#.*$//' sed removes all comments starting with '#'. This result in some complication, since now '#' character should not occur in string literals (like "#") - this will break compilation.
String literals has very limited use anyway. I've prepared some println() function, which I'd like to use as such:

println("Hello world");

Unfortunately it produces code as follows:

    .type   ..str,@object           # @.str
    .section        .rodata.str1.1,"aMS",@progbits,1
..str:
    .asciz  "Hello world"
    .size   ..str, 12

Error message:

{standard input}: Assembler messages:
{standard input}:632: Warning: unknown section attribute 'M'
{standard input}:632: Warning: unknown section attribute 'S'
{standard input}:632: Error: junk at end of line, first unrecognized character is `,'

The workaround is:

char msg[] = "Hello world";

println(msg);

Seems like GNU as does not understand .rodata notation. The same goes to all kinds of global constants:

const uint16_t i = 10;

turns into:

    .type   i,@object               # @i
    .section        .rodata,"a",@progbits
    .globl  i
    .align  2
i:
    .short  10                      # 0xa
    .size   i, 2

Error message:

{standard input}: Assembler messages:
{standard input}:630: Error: junk at end of line, first unrecognized character is `,'

The biggest encountered problem however is that llc sometimes produce invalid assembly code.
Suppose we have code like this:

#define FRAMEBUFFER ((volatile uint8_t *)(16384))
#define LINE_OFFSET(y) (((((y) >> 6) & 0b11) << 11) | ((((y) >> 3) & 0b111) << 5) | (((y) & 0b111) << 8))
#define SETPIXEL(x, y) (FRAMEBUFFER[LINE_OFFSET(y) | (((x) >> 3) & 0b11111)] |= ((0b10000000 >> ((x) & 0b111))))

uint8_t i;

for (i = 0; i < 192; i++) SETPIXEL(i, i + 8);

This will produce error as follows:

{standard input}: Assembler messages:
{standard input}:71: Error: illegal operand

Which is caused by following operation:

add hl, iy

Fortunately, it's typically possible to find some workaround, e.g. following code that do similar thing will compile:

uint8_t i, j;

for (i = 0, j = 8; i < 192; i++, j++) SETPIXEL(i, j);

@earl1k
Copy link
Owner

earl1k commented Apr 25, 2014

Thank you for your work on this problem. The code generator creates sometimes incorrect opcodes now. All these problems can be resolved in code generation module. This project is developed by me as a hobby. I will correct this errors in my free time.

@Ayymoose
Copy link

It's been 3 years since this was opened and 4 years since any work has been done on porting the Z80 architecture using LLVM here. Has your project died? Because I am interested in making this project work but I am a complete beginner to LLVM's backend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants