From ef71455a17c869d68dff9e045a45862abe0b3947 Mon Sep 17 00:00:00 2001 From: Bryan English Date: Wed, 11 Feb 2026 23:40:11 -0500 Subject: [PATCH] implement putstack in sorel --- docs/hacking.md | 2 -- sorel-ir/src/lib.rs | 1 + sorelc/src/ir.rs | 1 + sorelc/src/riscv_asm_codegen.rs | 18 ++++++++++++++++-- stdlib/out.sorel | 26 ++++++++++++++++++++++++++ tests/putstack.c | 16 ---------------- tests/test.sh | 3 +-- tests/test1.sorel | 6 ++---- 8 files changed, 47 insertions(+), 26 deletions(-) delete mode 100644 tests/putstack.c diff --git a/docs/hacking.md b/docs/hacking.md index fe7323d..afd8f77 100644 --- a/docs/hacking.md +++ b/docs/hacking.md @@ -70,5 +70,3 @@ target remote :4567 Then you can use normal gdb commands! The `tui layout asm` is highly recommended. -Note that if you'l linking `putstack.c`, that will use libc, which drastically inflates the binary and hijack's init. -This can make things quite a pain in `gdb`, so try to build without it (i.e. uncomment the LD line and comment out the CC line in `test.sh`, and remove all references to `putstack` in code). diff --git a/sorel-ir/src/lib.rs b/sorel-ir/src/lib.rs index 1a3ec27..d4e8e8f 100644 --- a/sorel-ir/src/lib.rs +++ b/sorel-ir/src/lib.rs @@ -38,6 +38,7 @@ pub enum IR { Over, Rot, StackPointer, + StackBottom, If, Else, EndIf, diff --git a/sorelc/src/ir.rs b/sorelc/src/ir.rs index 61e6115..7324af7 100644 --- a/sorelc/src/ir.rs +++ b/sorelc/src/ir.rs @@ -175,6 +175,7 @@ impl ImportTree { "over" => IR::Over, "rot" => IR::Rot, "sp" => IR::StackPointer, + "stackbottom" => IR::StackBottom, "if" => IR::If, "else" => IR::Else, "endif" => IR::EndIf, diff --git a/sorelc/src/riscv_asm_codegen.rs b/sorelc/src/riscv_asm_codegen.rs index c382cdf..23fba90 100644 --- a/sorelc/src/riscv_asm_codegen.rs +++ b/sorelc/src/riscv_asm_codegen.rs @@ -71,8 +71,8 @@ impl<'a> CodeGen<'a> { self.lines.push(line.to_string()); } - asm_macro!(copy_top_stack_value_to, "ld {}, 0(s2)", &str); - asm_macro!(copy_offset_stack_value_to, "ld {}, {}*8(s2)", &str, isize); + asm_macro!(copy_top_stack_value_to, "ld {}, 0(s2)", &str); + asm_macro!(copy_offset_stack_value_to, "ld {}, {}*8(s2)", &str, isize); asm_macro!(copy_to_top_of_stack, "sd {}, 0(s2)", &str); asm_macro!(move_stack_ptr_by_cells, "addi s2, s2, {}*8", isize); @@ -251,6 +251,15 @@ impl<'a> CodeGen<'a> { self.push_from("t0"); self.push_from("t1"); }, + IR::Over => { + // TODO this is super inefficient. There's no need to pop anything. Just read + // from the second stack position and push it. + self.label("# over"); + self.pop_some_to("t0 t1"); + self.push_from("t0"); + self.push_from("t1"); + self.push_from("t0"); + }, IR::Rot => { self.label("# rot"); self.pop_some_to("t0 t1 t2"); @@ -263,6 +272,11 @@ impl<'a> CodeGen<'a> { self.line("addi t0, s2, 0"); self.push_from("t0"); }, + IR::StackBottom => { + self.label("# stackbottom"); + self.line("la t0, data_stack_end"); + self.push_from("t0"); + } IR::Drop => { self.label("# drop"); self.move_stack_ptr_by_cells(1); diff --git a/stdlib/out.sorel b/stdlib/out.sorel index 5704f99..efe769e 100644 --- a/stdlib/out.sorel +++ b/stdlib/out.sorel @@ -57,3 +57,29 @@ export putn drop \ ( num ) ; +export putstack + +: putstack ( -- ) + sp stackbottom \ ( sp stack_end ) + swap \ ( stack_end sp ) + - \ ( stack_height_in_bytes ) + 8 \ ( stack_height_in_bytes cell_length ) + / \ ( stack_height_in_cells ) + dup dup \ ( stack_height_in_cells stack_height_in_cells stack_height_in_cells ) + "\n________________________________ stack top\n" puts drop + loop \ ( stack_height_in_cells index ) + over over \ ( stack_height_in_cells index stack_height_in_cells index ) + - \ (stack_height_in_cells index offset ) + sp 24 + \ ( stack_height_in_cells index offset sp ) \\\\ NOTE: We've added 3 cells to the stack, so need to rewind them here + swap 8 \ ( stack_height_in_cells index sp offset cell_length ) + * \ ( stack_height_in_cells index sp true_offset ) + + \ ( stack_height_in_cells index ptr_to_print ) + @ \ ( stack_height_in_cells index val_to_print ) + " " puts drop putn drop \ ( stack_height_in_cells index ) + 1 - \ ( stack_height_in_cells index-1 ) + dup \ ( stack_height_in_cells index-1 ) + endloop \ ( stack_height_in_cells 0 ) + drop drop \ () + "-------------------------------- stack bottom\n\n" puts drop +; + diff --git a/tests/putstack.c b/tests/putstack.c deleted file mode 100644 index a5200c4..0000000 --- a/tests/putstack.c +++ /dev/null @@ -1,16 +0,0 @@ -#include - -extern unsigned long data_stack_end; -register unsigned long * stack_pointer asm("s2"); - -void putstack() { - unsigned long * stack_index = &data_stack_end; - printf("stack: "); - while (stack_index != stack_pointer) { - printf("%ld ", *stack_index); - stack_index -= 1; - } - printf("%ld\n", *stack_pointer); -} - - diff --git a/tests/test.sh b/tests/test.sh index 279addc..ab7a145 100644 --- a/tests/test.sh +++ b/tests/test.sh @@ -6,6 +6,5 @@ CC="${CMD_PREFIX}cc" ../target/debug/sorelc test1.sorel $AS -g -o test1.o test1.asm -$CC -O1 -no-pie -o test1.out test1.o putstack.c -nostartfiles -# $LD -o test1.out test1.o +$LD -o test1.out test1.o ./test1.out diff --git a/tests/test1.sorel b/tests/test1.sorel index 3256625..ca868a4 100644 --- a/tests/test1.sorel +++ b/tests/test1.sorel @@ -20,11 +20,9 @@ import "std:string" import "std:mem" import "std:out" -extern putstack - 16 alloc \ ( ptr ) dup \ ( ptr ptr ) -"To be copied!" \ ( ptr ptr strptr ) +"To be copied!\n" \ ( ptr ptr strptr ) dup \ ( ptr ptr strptr strptr ) strlen 1 + \ ( ptr ptr strptr len ) rot \ ( ptr strptr len ptr ) @@ -33,4 +31,4 @@ memcopy \ ( ptr ) puts \ ( ptr ) free \ ( ) - +42 43 44 "soup" putstack -- 2.43.0