commit bca98081ec5ad5152a9f2c0450f178b765a9f034 Author: sam Date: Sun Apr 20 08:56:58 2025 +1200 first commit diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..c17e64a --- /dev/null +++ b/.clang-format @@ -0,0 +1,25 @@ +BasedOnStyle: WebKit +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +AlignConsecutiveDeclarations: false +AlignConsecutiveAssignments: false +AlignTrailingComments: true +ColumnLimit: 105 +BreakBeforeBraces: Attach +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortLambdasOnASingleLine: false +PointerAlignment: Left +SpaceBeforeParens: Never +SpacesInParentheses: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpaceAfterCStyleCast: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeSquareBrackets: false +SpacesBeforeTrailingComments: 2 +PenaltyBreakAssignment: 1000 +NamespaceIndentation: All + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f929eb3 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +CC=riscv64-linux-gnu-gcc +FILES=main.c transform.s +BINARY=transform + +$(BINARY): $(FILES) + $(CC) -o $(BINARY) $(FILES) + +run: $(BINARY) + ./$(BINARY) 127.0.0.1 + +clean: + rm $(BINARY) diff --git a/main.c b/main.c new file mode 100644 index 0000000..93b2c01 --- /dev/null +++ b/main.c @@ -0,0 +1,19 @@ +#include "transform.h" +#include +#include + +int main(int argc, char** argv) { + if(argc < 2) { + fprintf(stderr, "usage: %s \n", argv[0]); + return 1; + } + + char* result = transform(argv[1]); + if(result == NULL) { + fprintf(stderr, "Failed to allocate buffer\n"); + return 1; + } + + printf("%s\n", result); + free(result); +} diff --git a/transform b/transform new file mode 100755 index 0000000..42d807c Binary files /dev/null and b/transform differ diff --git a/transform.h b/transform.h new file mode 100644 index 0000000..5e9f425 --- /dev/null +++ b/transform.h @@ -0,0 +1,6 @@ +#ifndef TRANSFORM_H +#define TRANSFORM_H + +extern char* transform(char* str); + +#endif diff --git a/transform.s b/transform.s new file mode 100644 index 0000000..fda04d1 --- /dev/null +++ b/transform.s @@ -0,0 +1,99 @@ +.globl transform +.extern strlen +.extern malloc + +# this stuff didnt really need to be a macro but whatever +.macro begin_func + # regs reg size return address 16 byte align padding + addi sp, sp, -112 # 12 * 8 + 8 + 8 + sd ra, 104(sp) + sd s0, 96(sp) + sd s1, 88(sp) + sd s2, 80(sp) + sd s3, 72(sp) + sd s4, 64(sp) + sd s5, 56(sp) + sd s6, 48(sp) + sd s7, 40(sp) + sd s8, 32(sp) + sd s9, 24(sp) + sd s10, 16(sp) + sd s11, 8(sp) +.endm + +.macro end_func + ld ra, 104(sp) + ld s0, 96(sp) + ld s1, 88(sp) + ld s2, 80(sp) + ld s3, 72(sp) + ld s4, 64(sp) + ld s5, 56(sp) + ld s6, 48(sp) + ld s7, 40(sp) + ld s8, 32(sp) + ld s9, 24(sp) + ld s10, 16(sp) + ld s11, 8(sp) + addi sp, sp, 112 + ret +.endm + +.section .text +transform: + begin_func + + # s0 = input ip pointer + # s1 = input length + # s2 = buffer length + # s3 = buffer pointer + mv s0, a0 + call strlen + mv s1, a0 + + li t0, 3 + mul s2, s1, t0 # multiply input length by 3 to get maximum possible output length + + mv a0, s2 + addi a0, a0, 1 # add space for null terminator + call malloc + mv s3, a0 + beq s3, x0, .exit # if allocation failed exit the function + + mv t0, x0 # i + mv t1, x0 # out_i +.loop_start: + bge t0, s1, .loop_end # if i == len finish looping + + add t2, s0, t0 # t2 = ip + i + lb t3, 0(t2) # t3 has the char + li t5, '.' + bne t3, t5, .store_char # if the period isnt present skip adding the [ + + add t4, s3, t1 # t4 = buf + out_i + li t6, '[' + sb t6, 0(t4) # *t4 = '[' + addi t1, t1, 1 + +.store_char: + add t4, s3, t1 # t4 = buf + out_i + sb t3, 0(t4) # *t4 = t3 (the current char) + addi t0, t0, 1 + addi t1, t1, 1 + + bne t3, t5, .loop_start # if the period isnt present go back to start of loop + + add t4, s3, t1 # t4 = buf + out_i + li t6, ']' + sb t6, 0(t4) # *t4 = ']' + addi t1, t1, 1 + + j .loop_start + +.loop_end: + addi t4, t4, 1 + sb x0, 0(t4) # add null terminator + +.exit: + mv a0, s3 # put buffer into return register + end_func