summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfcomp.c36
-rw-r--r--epilogue.snippet.asm43
-rw-r--r--prologue.snippet.asm9
3 files changed, 65 insertions, 23 deletions
diff --git a/bfcomp.c b/bfcomp.c
index fa52087..4039856 100644
--- a/bfcomp.c
+++ b/bfcomp.c
@@ -45,7 +45,7 @@ void usage(const char *argv0){
"Uses nasm for assembling and gcc for linking.\n"
" -d Copies generated assembly to <srcfile>.asm\n"
" -h Show help\n"
- " -H Calculate heatmap while executing\n"
+ " -H <HMfname> Calculate heatmap while executing, writing data to <HMfname>\n"
" -L Output last cell reached\n"
" -m <memsize> Specify amount of tape cells (bytes) for the BF code\n"
" -v Show more info about the compile process\n",
@@ -60,9 +60,10 @@ __attribute__((noreturn)) void usage1(const char *argv0){
typedef struct Params{
int memsize;
const char *srcfname,*dstfname;
- bool lastcell,verbose,heatmap,copyasm;
+ bool lastcell,verbose,copyasm;
+ const char *heatmapfname;
} Params;
-Params params={30000,NULL,NULL,false,false,false,false};
+Params params={30000,NULL,NULL,false,false,false,NULL};
void parseargs(int argc,char **argv){
if(argc<2)usage1(argv[0]);
@@ -81,7 +82,9 @@ void parseargs(int argc,char **argv){
exit(0);
case 'H':
- params.heatmap=true;
+ if(i==argc-1)usage1(argv[0]);
+ params.heatmapfname=argv[i+1];
+ skipnext=true;
break;
case 'L':
@@ -195,12 +198,29 @@ int compilechain(const char *asmfname,const char *dstfname){
return ret;
}
+char hexdigit(int n){
+ if(n<0)return '?';
+ else if(n<10)return n+'0';
+ else if(n<16)return n-10+'a';
+ else return '?';
+}
+
void writesettings(FILE *asmf,Sourcemap *sm){
fprintf(asmf,"%%define PARAMS_MEMSIZE %d\n",params.memsize);
if(params.lastcell)fprintf(asmf,"%%define OUTPUT_LAST_CELL\n");
- if(params.heatmap){
+ if(params.heatmapfname){
assert(sm);
- fprintf(asmf,"%%define HEATMAP\n");
+ char buf[5*(strlen(params.heatmapfname)+1)];
+ int i;
+ for(i=0;i==0||params.heatmapfname[i-1];i++){
+ buf[5*i+0]='0';
+ buf[5*i+1]='x';
+ buf[5*i+2]=hexdigit(params.heatmapfname[i]/16);
+ buf[5*i+3]=hexdigit(params.heatmapfname[i]%16);
+ buf[5*i+4]=',';
+ }
+ buf[5*(i-1)+4]='\0';
+ fprintf(asmf,"%%define HEATMAPFNAME %s\n",buf);
fprintf(asmf,"%%define SOURCE_LENGTH %d\n",sm->origlen);
}
fputc('\n',asmf);
@@ -413,13 +433,13 @@ int main(int argc,char **argv){
char *source;
Sourcemap *sm1=NULL;
- readsource(srcf,&source,params.heatmap?&sm1:NULL);
+ readsource(srcf,&source,params.heatmapfname?&sm1:NULL);
assert(source);
fclose(srcf);
Sourcemap *sm2=NULL;
- optimise(source,sm1,params.heatmap?&sm2:NULL);
+ optimise(source,sm1,params.heatmapfname?&sm2:NULL);
char asmfname[20];
FILE *asmf=gettempfilew(asmfname);
diff --git a/epilogue.snippet.asm b/epilogue.snippet.asm
index b37d48b..7018fc1 100644
--- a/epilogue.snippet.asm
+++ b/epilogue.snippet.asm
@@ -18,30 +18,35 @@
call _write
%endif
-%ifdef HEATMAP
+%ifdef HEATMAPFNAME
+ lea rdi, [HMfname]
+ lea rsi, [HMfmode]
+ call _fopen
+ cmp rax, 0
+ jz fopenerror
+ mov r13, rax ;file pointer
+
mov ebx, 0 ;loop counter
hmloop:
- lea rdi, [strbuf64] ; snprintf(strbuf64,64,HMformatstr,ebx /*counter*/,r12[rbx])
- mov esi, 64
- lea rdx, [HMformatstr]
- mov ecx, ebx
- mov r8d, dword [r12+4*rbx]
- xor eax, eax
- call _snprintf
-
- mov edi, 2
- lea rsi, [strbuf64]
- mov edx, eax
- call _write
+ mov rdi, r13
+ lea rsi, [HMformatstr]
+ mov edx, ebx
+ mov ecx, dword [r12+4*rbx]
+ call _fprintf
inc ebx
cmp ebx, SOURCE_LENGTH
jl hmloop
+
+ mov rdi, r13
+ call _fclose
%endif
xor eax, eax
mainend:
+ pop r13
+ pop r13
pop r12
pop rbx
mov rsp, rbp
@@ -56,6 +61,12 @@ nomem:
mov eax, 1
jmp mainend
+fopenerror:
+ lea rdi, [fopenstr]
+ call _perror
+ mov eax, 1
+ jmp mainend
+
section .data
sectalign 8
@@ -70,7 +81,11 @@ nomemstr: db "Out of memory!"
maxp: dq 0
%endif
-%ifdef HEATMAP
+%ifdef HEATMAPFNAME
+ fopenstr: db "fopen", 0
+
+ HMfname: db HEATMAPFNAME
+ HMfmode: db "w", 0
HMformatstr: db "%d %d", 10, 0
%endif
diff --git a/prologue.snippet.asm b/prologue.snippet.asm
index a1768a4..294a60c 100644
--- a/prologue.snippet.asm
+++ b/prologue.snippet.asm
@@ -1,10 +1,14 @@
global _main
extern _calloc
+extern _fclose
extern _fflush
+extern _fopen
+extern _fprintf
extern _free
extern _getchar
extern _malloc
+extern _perror
extern _printf
extern _putchar
extern _snprintf
@@ -19,6 +23,8 @@ _main:
mov rbp, rsp
push rbx
push r12
+ push r13 ;for stack alignment
+ push r13
mov edi, PARAMS_MEMSIZE
call _malloc
cmp rax, 0
@@ -26,7 +32,7 @@ _main:
mov rbx, rax ;bufp
mov [buf], rax ;buf
-%ifdef HEATMAP
+%ifdef HEATMAPFNAME
mov edi, SOURCE_LENGTH
mov esi, 4
call _calloc
@@ -39,4 +45,5 @@ _main:
; rbx = bufp
; r12 = heatmap
+; r13 is used for the heatmap data file