From d45dbeb48a9da2ccfc1dd3fc0f3baea4c365e086 Mon Sep 17 00:00:00 2001 From: jakob Date: Sat, 18 Mar 2017 18:07:39 -0400 Subject: The compilation process now includes *very* minimal code optimization. --- skullfuck.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) (limited to 'skullfuck.c') diff --git a/skullfuck.c b/skullfuck.c index 7d9e0a8..b40e903 100644 --- a/skullfuck.c +++ b/skullfuck.c @@ -29,9 +29,13 @@ #define ARCH "x86_64" #define OS "Linux" #define INC_DATA_PTR "\tincq %rsi\n" +#define ADD_DATA_PTR "\taddq $0x%x, %%rsi\n" #define DEC_DATA_PTR "\tdecq %rsi\n" +#define SUB_DATA_PTR "\tsubq $0x%x, %%rsi\n" #define INC_DATA "\tincb (%rsi)\n" +#define ADD_DATA "\taddb $0x%x, (%%rsi)\n" #define DEC_DATA "\tdecb (%rsi)\n" +#define SUB_DATA "\tsubb $0x%x, (%%rsi)\n" #define PRINT_DATA "\tmovq $0x01, %rax\n" \ "\tmovq $0x01, %rdi\n" \ "\tsyscall\n" @@ -58,9 +62,13 @@ #define ARCH "i686" #define OS "Linux" #define INC_DATA_PTR "\tincl %ecx\n" +#define ADD_DATA_PTR "\taddl $0x%x, %%ecx\n" #define DEC_DATA_PTR "\tdecl %ecx\n" +#define SUB_DATA_PTR "\tsubl $0x%x, %%ecx\n" #define INC_DATA "\tincb (%ecx)\n" +#define ADD_DATA "\taddb $0x%x, (%%ecx)\n" #define DEC_DATA "\tdecb (%ecx)\n" +#define SUB_DATA "\tsubb $0x%x, (%%ecx)\n" #define PRINT_DATA "\tmovl $0x04, %eax\n" \ "\tmovl $0x01, %ebx\n" \ "\tint $0x80\n" @@ -121,26 +129,57 @@ static int pop_loop_index(struct loop_stack *s) { } +/* Minor optimization subroutine. Increments the `in` pointer to beyond + the collection of adjacent `op` characters, and returns the number + of operations counted. */ +static int reduce(char **in, char op) { + int i; + for (i = 0; (*in)[i] == op; i++); + *in += i - 1; + return i; +} + + /* Converts the brainfuck instructions read from `in` to assembly instructions and writes them to `out`. `in` is expected to be null-terminated. */ static void write_instructions(FILE *out, char *in) { - int next_loop = 0, cur_loop = 0; + int next_loop = 0, cur_loop = 0, op_count; struct loop_stack *loops = calloc(sizeof(struct loop_stack), 1); for (char *cur = in; *cur != '\0'; cur++) { switch(*cur) { case '>': - fputs(INC_DATA_PTR, out); + op_count = reduce(&cur, '>'); + if (op_count > 1) { + fprintf(out, ADD_DATA_PTR, op_count); + } else { + fputs(INC_DATA_PTR, out); + } break; case '<': - fputs(DEC_DATA_PTR, out); + op_count = reduce(&cur, '<'); + if (op_count > 1) { + fprintf(out, SUB_DATA_PTR, op_count); + } else { + fputs(DEC_DATA_PTR, out); + } break; case '+': - fputs(INC_DATA, out); + op_count = reduce(&cur, '+'); + if (op_count > 1) { + fprintf(out, ADD_DATA, op_count); + } else { + fputs(INC_DATA, out); + } break; case '-': - fputs(DEC_DATA, out); + op_count = reduce(&cur, '-'); + if (op_count > 1) { + fprintf(out, SUB_DATA, op_count); + } else { + fputs(DEC_DATA, out); + } break; case '.': fputs(PRINT_DATA, out); @@ -223,6 +262,10 @@ static void create_binary(struct params p) { wait(NULL); } } + + if (!p.compile_only) + remove("/tmp/skullfuck_tmp.s"); + remove("/tmp/skullfuck_tmp.o"); } -- cgit v1.3