Skip to content

Commit

Permalink
gcc: get basic libgcc setup working
Browse files Browse the repository at this point in the history
Having an actual linkable `libgcc.a` allows this port to define a
separate `crt0.S` startup routine which sets up the stack pointer and
halts the machine after `main()` finishes running.

This commit fixes some bugs along the way, most notably:
* missing bss from the linker script
* missing COMMON from the linker script (required for the `.lcomm` asm
  directive)
* miscellaneous bugs in the `c-test-arithmetic` sample

Signed-off-by: Filip Kokosiński <[email protected]>
  • Loading branch information
fkokosinski committed Jul 19, 2024
1 parent 669911c commit 4347b61
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 119 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/pdp1-playground.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ jobs:
# gcc doesn't support running `./configure` in the source directory
mkdir -p build-gcc
cd build-gcc
../pdp1-gcc/configure --target=pdp1-elf --enable-languages=c --disable-bootstrap
../pdp1-gcc/configure --target=pdp1-elf --enable-languages=c --disable-bootstrap --enable-gcov=no --enable-shared=no
make -j $(nproc) all-gcc
make -j $(nproc) all-target-libgcc
- name: Build samples
run: |
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ sudo make install
```
mkdir -p build-gcc
cd build-gcc
../pdp1-gcc/configure --target=pdp1-elf --enable-languages=c --disable-bootstrap
../pdp1-gcc/configure --target=pdp1-elf --enable-languages=c --disable-bootstrap --enable-gcov=no --enable-shared=no
make -j $(nproc) all-gcc
make -j $(nproc) all-target-libgcc
```

## Building and running samples
Expand Down
11 changes: 1 addition & 10 deletions c-print-array/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,8 @@ static int get_char(int);
static int x[] = {027, 030, 031};
static int i = 0;

void _start(void)
void main(void)
{
/* TODO: handle sp/fp init better -- separate crt0.S? */
asm volatile ("law 03000");
asm volatile ("dac 0131");
asm volatile ("law 04000");
asm volatile ("dac 0130");

/* check with no iterators */
putc(x[0]);
putc(x[1]);
Expand All @@ -30,9 +24,6 @@ void _start(void)
/* check with local iterator w/ func call */
for (int j = 0; j < 3; j++)
putc(x[j]);

asm volatile ("hlt");
__builtin_unreachable();
}

static void putc(int c) {
Expand Down
10 changes: 1 addition & 9 deletions c-print-fibonacci/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,14 @@ static int fib(int);

/* TODO: this sample fails to compile on higher -O values */

void _start(void)
void main(void)
{
asm volatile ("law 04000");
asm volatile ("dac 0131");
asm volatile ("law 03000");
asm volatile ("dac 0130");

int n;

for (int i = 0; i < 20; i++) {
puti(fib(i));
putc(033);
}

asm volatile ("hlt");
__builtin_unreachable();
}

static void putc(int c)
Expand Down
10 changes: 1 addition & 9 deletions c-print-for-loop/main.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
static void putc(int);
static int get_char(int);

void _start(void)
void main(void)
{
asm volatile ("law 04000");
asm volatile ("dac 0131");
asm volatile ("law 03000");
asm volatile ("dac 0130");

int c;

for (int i = 0; i != 8; i++) {
c = get_char(i);
putc(c);
}

asm volatile ("hlt");
__builtin_unreachable();
}

static void putc(int c) {
Expand Down
11 changes: 1 addition & 10 deletions c-print-struct/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,15 @@ static struct {
short field3;
} x;

void _start(void)
void main(void)
{
asm volatile ("law 04000");
asm volatile ("dac 0131");
asm volatile ("law 03000");
asm volatile ("dac 0130");

x.field1 = 027;
x.field2 = 030;
x.field3 = 031;

putc(x.field1);
putc(x.field2);
putc(x.field3);


asm ("hlt");
__builtin_unreachable();
}

static void putc(int c) {
Expand Down
11 changes: 1 addition & 10 deletions c-print-x/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,12 @@ int x = 027;
/* unitialized global var - gcc should emit `.skip` */
int y;

void _start(void)
void main(void)
{
asm volatile ("law 04000");
asm volatile ("dac 0131");
asm volatile ("law 03000");
asm volatile ("dac 0130");

asm volatile ("lio %0" : : "r"(x) : "$io");
asm volatile ("tyo");

y = 027;
asm volatile ("lio %0" : : "r"(y) : "$io");
asm volatile ("tyo");

asm volatile ("hlt");

__builtin_unreachable();
}
45 changes: 18 additions & 27 deletions c-test-arith/main.c
Original file line number Diff line number Diff line change
@@ -1,65 +1,56 @@
int x = 21;
int y = 37;

void _start(void)
void main(void)
{
/* TODO: handle sp/fp init better -- separate crt0.S? */
asm volatile ("law 03000");
asm volatile ("dac 0131");
asm volatile ("law 04000");
asm volatile ("dac 0130");

/* test addition with two variables */
*(volatile int *)(01000) = x + y;
*(volatile int *)(02000) = x + y;

/* test addition with an immediate value */
*(volatile int *)(01001) = x + 20;
*(volatile int *)(02001) = x + 20;

/* test addition with an immediate value equal 1 */
*(volatile int *)(01002) = x + 1;
*(volatile int *)(02002) = x + 1;

/* test subtraction with two variables */
*(volatile int *)(01003) = y - x;
*(volatile int *)(02003) = y - x;

/* test subtraction with an immediate value */
*(volatile int *)(01004) = y - 10;
*(volatile int *)(02004) = y - 10;

/* test multiplication with two variables */
*(volatile int *)(01005) = x * y;
*(volatile int *)(02005) = x * y;

/* test division with two variables */
*(volatile int *)(01006) = y / x;
*(volatile int *)(02006) = y / x;

/* test modulo with two variables */
*(volatile int *)(01007) = y % x;
*(volatile int *)(02007) = y % x;

/* test logical negation with a variable */
*(volatile int *)(01010) = ~x;
*(volatile int *)(02010) = ~x;

/* test logical and with two variables */
*(volatile int *)(01011) = x & y;
*(volatile int *)(02011) = x & y;

/* test logical and with an immediate value */
*(volatile int *)(01012) = x & 12;
*(volatile int *)(02012) = x & 12;

/* test logical or with two variables */
*(volatile int *)(01013) = x | y;
*(volatile int *)(02013) = x | y;

/* test logical or with an immediate value */
*(volatile int *)(01014) = x | 12;
*(volatile int *)(02014) = x | 12;

/* test logical xor with two variables */
*(volatile int *)(01015) = x ^ y;
*(volatile int *)(02015) = x ^ y;

/* test logical xor with an immediate value */
*(volatile int *)(01016) = x ^ 12;
*(volatile int *)(02016) = x ^ 12;

/* test shift left */
*(volatile int *)(01016) = x << 6;
*(volatile int *)(02017) = x << 6;

/* test shift right */
*(volatile int *)(01017) = x >> 3;

asm volatile ("hlt");
__builtin_unreachable();
*(volatile int *)(02020) = x >> 3;
}
11 changes: 1 addition & 10 deletions c-test-comparison/main.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
static void putc(int);

void _start(void)
void main(void)
{
/* TODO: handle sp/fp init better -- separate crt0.S? */
asm volatile ("law 03000");
asm volatile ("dac 0131");
asm volatile ("law 04000");
asm volatile ("dac 0130");

int x = 30;
int y = 30;

Expand Down Expand Up @@ -43,9 +37,6 @@ void _start(void)
x = 21;
if (x > y)
putc(071); // i

asm volatile ("hlt");
__builtin_unreachable();
}

static void putc(int c) {
Expand Down
11 changes: 1 addition & 10 deletions c-test-recursion/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,9 @@ static void putc();

static void foo(int);

void _start(void)
void main(void)
{
/* TODO: handle sp/fp init better -- separate crt0.S? */
asm volatile ("law 03000");
asm volatile ("dac 0131");
asm volatile ("law 04000");
asm volatile ("dac 0130");

foo(20);

asm volatile ("hlt");
__builtin_unreachable();
}

static void putc() {
Expand Down
23 changes: 23 additions & 0 deletions common/common.ld
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,38 @@ MEMORY
ram (rwx) : ORIGIN = 0x0, LENGTH = 64K
}

STACK_SIZE = 01000;

SECTIONS
{
.text 0x12c :
{
/*
* We need to have crt0 at the start, because we depend on the
* `_start` symbol being at 0x12c.
*
* TODO: make this configurable/flexible in BFD dec-rim backend
*/
"../common/crt0.o"(.text)

*(.text)
} > ram

.bss (NOLOAD) :
{
*(.bss .bss.*)
*(COMMON)
} > ram

.data :
{
*(.data)
} > ram

.stack (NOLOAD) :
{
_stack_start = .;
. += STACK_SIZE;
_stack_end = .;
} > ram
}
10 changes: 5 additions & 5 deletions common/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@ APP_NAME ?= main
CCFLAGS ?= -O0
objects-asm := $(patsubst %.S,%.o,$(wildcard *.S))
objects-c := $(patsubst %.c,%.o,$(wildcard *.c))
objects := $(objects-asm) $(objects-c)
objects := $(objects-asm) $(objects-c) ../common/crt0.o

default: $(APP_NAME).rim

%.s: %.c
../build-gcc/gcc/cc1 $(CCFLAGS) $<
$(realpath ../build-gcc/gcc/cc1) $(CCFLAGS) $<

%.o: %.S
pdp1-elf-as $< -o $@

%.o: %.s
pdp1-elf-as $< -o $@

$(APP_NAME).bin: ../common/common.ld $(objects)
pdp1-elf-ld -o $@ -T $^
$(APP_NAME).bin: $(realpath ../common/common.ld) $(objects)
pdp1-elf-ld -L$(realpath ../build-gcc/gcc) -o $@ -T $^ -lgcc

%.rim: %.bin
pdp1-elf-objcopy -O dec_rim $< $@

run: $(APP_NAME).rim
pdp1 ../common/startup.pdp1
pdp1 $(realpath ../common/startup.pdp1)

clean:
rm -rf *.o *.s *.bin *.rim
Expand Down
11 changes: 11 additions & 0 deletions common/crt0.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.global _start
_start:
# stack pointer
law _stack_end
dac 0131

# jump to main
jsp main

# stop
hlt
33 changes: 17 additions & 16 deletions tests/test.exp
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,22 @@ run_print_test "c-test-recursion" "xxxxxxxxxxxxxxxxxxxx"
run_print_test "c-print-fibonacci" "0,1,1,2,3,5,8,31,12,43,55,98,441,332,773,016,789,7951,4852,1814,"

# run tests that set values in memory
set mem [dict create "1000" "000072" \
"1001" "000051" \
"1002" "000026" \
"1003" "000020" \
"1004" "000033" \
"1005" "001411" \
"1006" "000001" \
"1007" "000020" \
"1010" "777752" \
"1011" "000005" \
"1012" "000004" \
"1013" "000065" \
"1014" "000035" \
"1015" "000060" \
"1016" "002500" \
"1017" "000002"]
set mem [dict create "2000" "000072" \
"2001" "000051" \
"2002" "000026" \
"2003" "000020" \
"2004" "000033" \
"2005" "001411" \
"2006" "000001" \
"2007" "000020" \
"2010" "777752" \
"2011" "000005" \
"2012" "000004" \
"2013" "000065" \
"2014" "000035" \
"2015" "000060" \
"2016" "000031" \
"2017" "002500" \
"2020" "000002"]

run_memory_test "c-test-arith" "" $mem

0 comments on commit 4347b61

Please sign in to comment.