Skip to content

Commit

Permalink
allow address of spin functions to be taken
Browse files Browse the repository at this point in the history
  • Loading branch information
totalspectrum committed Dec 19, 2019
1 parent a1a1dee commit 4f27abc
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 22 deletions.
1 change: 1 addition & 0 deletions Changelog.txt
Expand Up @@ -10,6 +10,7 @@ Version 4.0.5
- Print errors for function declared twice
- Re-arranged internal code to make it possible to distinguish C vs C++ or spin1 vs spin2
- Allow empty parameter lists in Spin
- Allow address of function to be taken in Spin
- Added checks for redefined constants

Version 4.0.4
Expand Down
34 changes: 17 additions & 17 deletions Test/Expect/stest184.pasm
Expand Up @@ -28,24 +28,24 @@ LR__0001
_fetchv_ret
ret

__system___tx
mov __system___tx_val, arg01
rdlong __system___tx_bitcycles, ptr___system__dat__
__system___txraw
mov __system___txraw_val, arg01
rdlong __system___txraw_bitcycles, ptr___system__dat__
or outa, imm_1073741824_
or dira, imm_1073741824_
or __system___tx_val, #256
shl __system___tx_val, #1
mov __system___tx_nextcnt, cnt
mov __system___tx__idx__90001, #10
or __system___txraw_val, #256
shl __system___txraw_val, #1
mov __system___txraw_nextcnt, cnt
mov __system___txraw__idx__90001, #10
LR__0002
add __system___tx_nextcnt, __system___tx_bitcycles
mov arg01, __system___tx_nextcnt
add __system___txraw_nextcnt, __system___txraw_bitcycles
mov arg01, __system___txraw_nextcnt
waitcnt arg01, #0
shr __system___tx_val, #1 wc
shr __system___txraw_val, #1 wc
muxc outa, imm_1073741824_
djnz __system___tx__idx__90001, #LR__0002
djnz __system___txraw__idx__90001, #LR__0002
mov result1, #1
__system___tx_ret
__system___txraw_ret
ret

__system___gc_pageptr
Expand Down Expand Up @@ -204,7 +204,7 @@ LR__0008
add __system___gc_errmsg_s, #1
if_e jmp #LR__0009
mov arg01, __system___gc_errmsg_c
call #__system___tx
call #__system___txraw
jmp #LR__0008
LR__0009
mov result1, #0
Expand Down Expand Up @@ -793,13 +793,13 @@ __system___gc_tryalloc_saveptr
res 1
__system___gc_tryalloc_size
res 1
__system___tx__idx__90001
__system___txraw__idx__90001
res 1
__system___tx_bitcycles
__system___txraw_bitcycles
res 1
__system___tx_nextcnt
__system___txraw_nextcnt
res 1
__system___tx_val
__system___txraw_val
res 1
__system__bytemove_origdst
res 1
Expand Down
14 changes: 11 additions & 3 deletions frontends/spin/spinlang.c
Expand Up @@ -214,8 +214,16 @@ ScanFunctionBody(Function *fdef, AST *body, AST *upper, AST *expectType)
lab->flags |= (LABEL_NEEDS_EXTRA_ALIGN|LABEL_USED_IN_SPIN);
WARNING(body, "Label is dereferenced with greater alignment than it was declared with");
}

}
} else if (sym && sym->kind == SYM_FUNCTION) {
// insert an explicit function address
extern AST *FunctionAddress(AST *); // in types.c
AST *getaddr = FunctionAddress(body->left);
if (upper->left == body) {
upper->left = getaddr;
return;
}
WARNING(body, "Taking address of function not supported yet in Spin");
}
}
} else if (ast->kind == AST_RESULT) {
/* hack to make F32.spin work: it expects all variables
Expand Down Expand Up @@ -264,7 +272,7 @@ ScanFunctionBody(Function *fdef, AST *body, AST *upper, AST *expectType)
}
// convert plain IDENTIFIER into a FUNCCALL if it is a function
// identifier
if (sym->kind == SYM_FUNCTION && upper && upper->kind != AST_FUNCCALL) {
if (sym->kind == SYM_FUNCTION && upper && upper->kind != AST_FUNCCALL && upper->kind != AST_ADDROF) {
AST *funccall;
ASTReportInfo saveinfo;
AstReportAs(body, &saveinfo);
Expand Down
8 changes: 6 additions & 2 deletions frontends/types.c
Expand Up @@ -67,7 +67,8 @@ static AST *gc_free;

static AST *funcptr_cmp;

static AST *BuildMethodPointer(AST *ast);
AST *BuildMethodPointer(AST *ast);
static AST * getBasicPrimitive(const char *name);

bool VerifyIntegerType(AST *astForError, AST *typ, const char *opname)
{
Expand Down Expand Up @@ -1003,7 +1004,7 @@ doCast(AST *desttype, AST *srctype, AST *src)
return NULL;
}

static AST *
AST *
BuildMethodPointer(AST *ast)
{
Symbol *sym;
Expand All @@ -1029,6 +1030,9 @@ BuildMethodPointer(AST *ast)
// save off the current @ node
funcaddr = NewAST(AST_ADDROF, ast->left, ast->right);
// create a call
if (!make_methodptr) {
make_methodptr = getBasicPrimitive("_make_methodptr");
}
result = MakeOperatorCall(make_methodptr, objast, funcaddr, NULL);
return result;
}
Expand Down

0 comments on commit 4f27abc

Please sign in to comment.