Skip to content
This repository was archived by the owner on Jul 7, 2023. It is now read-only.

Commit 6bcf07b

Browse files
added one more optimisation
basically, branchless execution, but because it's less predictable with memory usage you need to at least double the memory footprint.
1 parent 00638e7 commit 6bcf07b

File tree

10 files changed

+270
-43
lines changed

10 files changed

+270
-43
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ bfcli : $(OBJS) $(LIBS)
6060
$(CC) $(CFLAGS) $(OBJS) -o bfcli $(LDLIBS)
6161

6262
$(DSFILES) : %.s : demo/%.bf bfcli
63-
./bfcli -sO1 $< -o $@
63+
./bfcli -sO2 $< -o $@
6464

6565
$(DOBJS) : %.o : %.s
6666
$(AS) $(DSFLAGS) $< -o $@

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Bfcli: The Interactive Brainfuck Command-Line Interpreter
22
```
33
Copyright (C) 2021 Jyothiraditya Nellakra
4-
Version 9.3: Cheesecake
4+
Version 9.4: A Slightly Soggy Burger
55
66
bfcli:0%
77
```
@@ -90,8 +90,8 @@ The following are the command-line arguments that this program accepts:
9090
-A, --arch ARCH Sets the assembly architecture to ARCH. Valid values are
9191
amd64 and i386.
9292
93-
-O, --optim LVL Sets the optimisation level to LVL. Valid values are 0
94-
and 1.
93+
-O, --optim LVL Sets the optimisation level to LVL. Valid values are 0, 1
94+
and 2.
9595
9696
Note: If no output file is specified, a filename is chosen automatically.
9797

demo/factor.bf

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#! /bin/bf
2+
3+
* Factor an Arbitrarily Large Positive Integer
4+
*
5+
* Copyright (C) 1999 by Brian Raiter
6+
* Under the GNU General Public License
7+
8+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>-
9+
10+
*
11+
* read in the number
12+
*
13+
14+
<<<<<<<<<+
15+
[-[>>>>>>>>>>][-]<<<<<<<<<<[[->>>>>>>>>>+<<<<<<<<<<]<<<<<<<<<<]
16+
>>>>>>>>>>,----------]
17+
>>>>>>>>>>[------------------------------------->>>>>>>>>->]
18+
<[+>[>>>>>>>>>+>]<-<<<<<<<<<<]-
19+
20+
*
21+
* display the number and initialize the loop variable to two
22+
*
23+
24+
[>++++++++++++++++++++++++++++++++++++++++++++++++.
25+
------------------------------------------------<<<<<<<<<<<]
26+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.
27+
--------------------------.[-]
28+
>>>>>>>>>>>>++<<<<+
29+
30+
*
31+
* the main loop
32+
*
33+
34+
[ [-]>>
35+
36+
*
37+
* make copies of the number and the loop variable
38+
*
39+
40+
[>>>>[-]>[-]>[-]>[-]
41+
>[-]>[-]
42+
<<<<<<<[->>>+>+<<<<]>>>>>>>>]
43+
<<<<<<<<<<[>>>>>>[-<<<<+>>>>]<<<<<<<<<<<<<<<<]>>>>>>>>>>
44+
[>[->>>+>>+<<<<<]>>>>>>>>>]
45+
<<<<<<<<<<[>>>>>>[-<<<<<+>>>>>]<<<<<<<<<<<<<<<<]>>>>>>>>>>
46+
47+
*
48+
* divide the number by the loop variable
49+
*
50+
51+
[>>>[-]>>>[-]>[-]>>>] initialize
52+
<<<<<<<<<<[<<<<<<<<<<]
53+
>>>>>>>>>[-]>>>>>>>+<<<<<<<<[+]+
54+
[ ->> double divisor until above dividend
55+
[>>>>>>[->++<]>>>>]<<<<<<<<<<
56+
[>>>>>>>>[-]>[-]
57+
<<<<[->>>++<<<]<<<<<<<<<<<<<<<]>>>>>>>>>>
58+
[>>>>>>>>[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<
59+
[->--------->>>>>>>>>+<<<<<<<<<<[->+<]]]]]]]]]]]>>]
60+
<<<<<<<<<<[>>>>>>>>>[-<+<<<+>>>>]<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>
61+
[>>>>>>>[-<+>[-<+>[-<+>[-<+>[-<+>[-<+>[-<+>[-<+>[-<+>
62+
[-<--------->>>>>>>>>>>+<<<<<<<<<<[-<+>]]]]]]]]]]]>>>]
63+
<<<<<<<<<<
64+
[>>>>[->>>+>>+<<<<<]<<<<<<<<<<<<<<]
65+
>>>>>>>>>>[>>>>>>>[-<<<+>>>]>>>]<<<<<<<<<<
66+
[>>>>>>>>[->-<]>
67+
[<<<<<<<<<[<[-]>>>>>>>>>>[-<<<<<<<<<<+>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<]
68+
>>>>>>>>>>>>>>>>>>>]
69+
<<<<<<<<<<<<<<<<<<<]
70+
>>>>>>>>>[+[+[+[+[+[+[+[+[+[+[[-]<+>]]]]]]]]]]]<
71+
]
72+
>>>>>>>>
73+
[ subtract divisor from dividend
74+
<<<<<<
75+
[>>>>>>>>[-]>[-]<<<<<[->>>+>+<<<<]>>>>>>]<<<<<<<<<<
76+
[>>>>>>>>[-<<<<+>>>>]<<<[->>>+>+<<<<]<<<<<<<<<<<<<<<]>>>>>>>>>>
77+
[>>>>>>>>>[-<<<<+>>>>]>]<<<<<<<<<<
78+
[>>>>>>>>[-<->]<<<<<<<<<<<<<<<<<<]>>>>>>>>>>
79+
[>>>>>>>[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<
80+
[++++++++++[+>-<]>>>>>>>>>>-<<<<<<<<<<]]]]]]]]]]]>>>]
81+
>>>>>>>+
82+
[ if difference is nonnegative then
83+
[-]<<<<<<<<<<<<<<<<< replace dividend and increment quotient
84+
[>>>>[-]>>>>[-<<<<+>>>>]<<[->>+<<]<<<<<<<<<<<<<<<<]>>>>>>>>>>
85+
[>>>>>>>>[->+<<<+>>]>>]<<<<<<<<<<
86+
[>>>[->>>>>>+<<<<<<]<<<<<<<<<<<<<]>>>>>>>>>>
87+
[>>>>>>>>>[-<<<<<<+>>>>>>[-<<<<<<+>>>>>>
88+
[-<<<<<<+>>>>>>[-<<<<<<+>>>>>>
89+
[-<<<<<<+>>>>>>[-<<<<<<+>>>>>>
90+
[-<<<<<<+>>>>>>[-<<<<<<+>>>>>>
91+
[-<<<<<<+>>>>>>[-<<<<<<--------->>>>>>>>>>>>>>>>+<<<<<<<<<<
92+
[-<<<<<<+>>>>>>]]]]]]]]]]]>]
93+
>>>>>>>
94+
] halve divisor and loop until zero
95+
<<<<<<<<<<<<<<<<<[<<<<<<<<<<]>>>>>>>>>>
96+
[>>>>>>>>[-]<<[->+<]<[->>>+<<<]>>>>>]<<<<<<<<<<
97+
[+>>>>>>>[-<<<<<<<+>>>>>>>[-<<<<<<<->>>>>>+>
98+
[-<<<<<<<+>>>>>>>[-<<<<<<<->>>>>>+>
99+
[-<<<<<<<+>>>>>>>[-<<<<<<<->>>>>>+>
100+
[-<<<<<<<+>>>>>>>[-<<<<<<<->>>>>>+>
101+
[-<<<<<<<+>>>>>>>]]]]]]]]]<<<<<<<
102+
[->>>>>>>+<<<<<<<]-<<<<<<<<<<]
103+
>>>>>>>
104+
[-<<<<<<<<<<<+>>>>>>>>>>>]
105+
>>>[>>>>>>>[-<<<<<<<<<<<+++++>>>>>>>>>>>]>>>]<<<<<<<<<<
106+
[+>>>>>>>>[-<<<<<<<<+>>>>>>>>[-<<<<<<<<->>>>>+>>>
107+
[-<<<<<<<<+>>>>>>>>[-<<<<<<<<->>>>>+>>>
108+
[-<<<<<<<<+>>>>>>>>[-<<<<<<<<->>>>>+>>>
109+
[-<<<<<<<<+>>>>>>>>[-<<<<<<<<->>>>>+>>>
110+
[-<<<<<<<<+>>>>>>>>]]]]]]]]]<<<<<<<<
111+
[->>>>>>>>+<<<<<<<<]-<<<<<<<<<<]
112+
>>>>>>>>[-<<<<<<<<<<<<<+>>>>>>>>>>>>>]>>
113+
[>>>>>>>>[-<<<<<<<<<<<<<+++++>>>>>>>>>>>>>]>>]<<<<<<<<<<
114+
[<<<<<<<<<<]>>>>>>>>>>
115+
>>>>>>
116+
]
117+
<<<<<<
118+
119+
*
120+
* make copies of the loop variable and the quotient
121+
*
122+
123+
[>>>[->>>>+>+<<<<<]>>>>>>>]
124+
<<<<<<<<<<
125+
[>>>>>>>[-<<<<+>>>>]<<<<<[->>>>>+>>+<<<<<<<]<<<<<<<<<<<<]
126+
>>>>>>>>>>[>>>>>>>[-<<<<<+>>>>>]>>>]<<<<<<<<<<
127+
128+
*
129+
* break out of the loop if the quotient is larger than the loop variable
130+
*
131+
132+
[>>>>>>>>>[-<->]<
133+
[<<<<<<<<
134+
[<<[-]>>>>>>>>>>[-<<<<<<<<<<+>>>>>>>>>>]<<<<<<<<<<<<<<<<<<]
135+
>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<]
136+
>>>>>>>>[>-<[+[+[+[+[+[+[+[+[+[[-]>+<]]]]]]]]]]]>+
137+
138+
[ [-]
139+
140+
*
141+
* partially increment the loop variable
142+
*
143+
144+
<[-]+>>>>+>>>>>>>>[>>>>>>>>>>]<<<<<<<<<<
145+
146+
*
147+
* examine the remainder for nonzero digits
148+
*
149+
150+
[<<<<<<[<<<<[<<<<<<<<<<]>>>>+<<<<<<<<<<]<<<<]
151+
>>>>>>>>>>>>>>>>>>>>[>>>>>>>>>>]<<<<<<<<<<[<<<<<<<<<<]
152+
>>>>-
153+
154+
[ [+]
155+
156+
*
157+
* decrement the loop variable and replace the number with the quotient
158+
*
159+
160+
>>>>>>>>-<<[>[-]>>[-<<+>>]>>>>>>>]<<<<<<<<<<
161+
162+
*
163+
* display the loop variable
164+
*
165+
166+
[+>>[>>>>>>>>+>>]<<-<<<<<<<<<<]-
167+
[>>++++++++++++++++++++++++++++++++++++++++++++++++.
168+
------------------------------------------------<<<<<<<<<<<<]
169+
++++++++++++++++++++++++++++++++.[-]>>>>
170+
171+
]
172+
173+
*
174+
* normalize the loop variable
175+
*
176+
177+
>>>>>>
178+
[>>[->>>>>+<<<<<[->>>>>+<<<<<
179+
[->>>>>+<<<<<[->>>>>+<<<<<
180+
[->>>>>+<<<<<[->>>>>+<<<<<
181+
[->>>>>+<<<<<[->>>>>+<<<<<
182+
[->>>>>+<<<<<[->>>>>--------->>>>>+<<<<<<<<<<
183+
[->>>>>+<<<<<]]]]]]]]]]]>>>>>>>>]
184+
<<<<<<<<<<[>>>>>>>[-<<<<<+>>>>>]<<<<<<<<<<<<<<<<<]
185+
>>>>>>>>>
186+
187+
]<
188+
189+
]>>
190+
191+
*
192+
* display the number and end
193+
*
194+
195+
[>>>>>>>>>>]<<<<<<<<<<[+>[>>>>>>>>>+>]<-<<<<<<<<<<]-
196+
[>++++++++++++++++++++++++++++++++++++++++++++++++.<<<<<<<<<<<]
197+
++++++++++.

src/arch/amd64.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
#include "../translator.h"
3030

3131
void BFa_amd64_tasm(FILE *file) {
32-
fprintf(file, ".bss\n\n");
32+
fprintf(file, ".bss\n");
33+
if(BFt_optim_lvl >= 2) fprintf(file, "\t.skip\t%zu\n", BFi_mem_size);
34+
fprintf(file, "\n");
35+
3336
fprintf(file, "cells:\n");
3437
fprintf(file, "\t.skip\t%zu\n\n", BFi_mem_size);
3538

@@ -444,7 +447,9 @@ void BFa_amd64_tc(FILE *file) {
444447
}
445448
}
446449

447-
fprintf(file, "\n\t: : \"r\" (&cells[0])\n");
450+
fprintf(file, "\n\t: : \"r\" (&cells[%zu])\n",
451+
BFt_optim_lvl >= 2 ? BFi_mem_size : 0);
452+
448453
fprintf(file, "\t: \"rax\", \"rbx\", \"rcx\", \"rdx\", \"rdi\",\n"
449454
"\t\"rsi\", \"r8\", \"r9\", \"r10\", \"r11\");\n\n");
450455

src/arch/i386.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
#include "../translator.h"
3030

3131
void BFa_i386_tasm(FILE *file) {
32-
fprintf(file, ".bss\n\n");
32+
fprintf(file, ".bss\n");
33+
if(BFt_optim_lvl >= 2) fprintf(file, "\t.skip\t%zu\n", BFi_mem_size);
34+
fprintf(file, "\n");
35+
3336
fprintf(file, "cells:\n");
3437
fprintf(file, "\t.skip\t%zu\n\n", BFi_mem_size);
3538

@@ -434,7 +437,9 @@ void BFa_i386_tc(FILE *file) {
434437
}
435438
}
436439

437-
fprintf(file, "\n\t: : \"r\" (&cells[0])\n");
440+
fprintf(file, "\n\t: : \"r\" (&cells[%zu])\n",
441+
BFt_optim_lvl >= 2 ? BFi_mem_size : 0);
442+
438443
fprintf(file, "\t: \"eax\", \"ebx\", \"ecx\", \"edx\", \"esi\");\n\n");
439444

440445
fprintf(file, "\treturn 0;\n");

src/interpreter.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ static BFi_instr_t *compile(char *str, bool enable_exts) {
9393
first -> prev = NULL;
9494
first -> next = NULL;
9595
first -> opcode = BFI_INSTR_NOP;
96-
first -> operand.ptr = NULL;
97-
first -> operand.value = 0;
96+
first -> op.ptr = NULL;
97+
first -> op.value = 0;
9898

9999
BFi_instr_t *current = first;
100100
size_t length = strlen(str);
@@ -149,8 +149,8 @@ static BFi_instr_t *compile(char *str, bool enable_exts) {
149149
else break;
150150
}
151151

152-
j -> operand.ptr = current;
153-
current -> prev -> operand.ptr = j;
152+
j -> op.ptr = current;
153+
current -> prev -> op.ptr = j;
154154
continue;
155155
}
156156

@@ -189,7 +189,7 @@ static BFi_instr_t *compile(char *str, bool enable_exts) {
189189

190190
if(value) {
191191
current -> opcode = opcode;
192-
current -> operand.value = value;
192+
current -> op.value = value;
193193
}
194194

195195
return first;
@@ -200,17 +200,17 @@ static void run(BFi_instr_t *instr) {
200200
while(instr && BFi_is_running) {
201201
switch(instr -> opcode) {
202202
case BFI_INSTR_INC:
203-
BFi_mem[BFi_mem_ptr] += instr -> operand.value;
203+
BFi_mem[BFi_mem_ptr] += instr -> op.value;
204204
break;
205205

206206
case BFI_INSTR_DEC:
207-
BFi_mem[BFi_mem_ptr] -= instr -> operand.value;
207+
BFi_mem[BFi_mem_ptr] -= instr -> op.value;
208208
break;
209209

210210
case BFI_INSTR_FWD:
211-
BFi_mem_ptr += instr -> operand.value;
211+
BFi_mem_ptr += instr -> op.value;
212212
if(BFi_mem_ptr >= BFi_mem_size) {
213-
BFi_mem_ptr -= instr -> operand.value;
213+
BFi_mem_ptr -= instr -> op.value;
214214

215215
BFe_file_name = BFc_immediate
216216
? BFf_mainfile_name
@@ -227,9 +227,9 @@ static void run(BFi_instr_t *instr) {
227227
break;
228228

229229
case BFI_INSTR_BCK:
230-
BFi_mem_ptr -= instr -> operand.value;
230+
BFi_mem_ptr -= instr -> op.value;
231231
if(BFi_mem_ptr >= BFi_mem_size) {
232-
BFi_mem_ptr += instr -> operand.value;
232+
BFi_mem_ptr += instr -> op.value;
233233

234234
BFe_file_name = BFc_immediate
235235
? BFf_mainfile_name
@@ -256,12 +256,12 @@ static void run(BFi_instr_t *instr) {
256256
break;
257257

258258
case BFI_INSTR_JMP:
259-
instr = instr -> operand.ptr;
259+
instr = instr -> op.ptr;
260260
continue;
261261

262262
case BFI_INSTR_JZ:
263263
if(BFi_mem[BFi_mem_ptr]) break;
264-
instr = instr -> operand.ptr;
264+
instr = instr -> op.ptr;
265265
continue;
266266

267267
case BFI_INSTR_HELP:
@@ -370,7 +370,7 @@ static void append_cmplx(BFi_instr_t **current, int *opcode, size_t *value,
370370

371371
else if(*opcode != context) {
372372
(*current) -> opcode = *opcode;
373-
(*current) -> operand.value = *value;
373+
(*current) -> op.value = *value;
374374

375375
(*current) -> next = malloc(sizeof(BFi_instr_t));
376376
if(!(*current) -> next) BFe_report_err(BFE_UNKNOWN_ERROR);

src/interpreter.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,10 @@
2121
#define BF_INTERPRETER_H 1
2222

2323
typedef struct BFi_instr_s {
24+
union { struct BFi_instr_s *ptr; size_t value; } op;
2425
struct BFi_instr_s *prev, *next;
2526
int opcode;
2627

27-
union {
28-
struct BFi_instr_s *ptr;
29-
size_t value;
30-
31-
} operand;
32-
3328
#define BFI_INSTR_NOP 0
3429

3530
#define BFI_INSTR_INC 1

src/main.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
#define BF_MAIN_H 1
2222

2323
#define BF_VERSION 9
24-
#define BF_SUBVERSION 3
25-
#define BF_VERNAME "Cheesecake"
24+
#define BF_SUBVERSION 4
25+
#define BF_VERNAME "A Slightly Soggy Burger"
2626

2727
#define BF_LINE_SIZE 4096
2828
#define BF_CODE_SIZE 65536

0 commit comments

Comments
 (0)