Skip to content

Commit

Permalink
New way of putting objects at end of member variables
Browse files Browse the repository at this point in the history
  • Loading branch information
totalspectrum committed Oct 26, 2021
1 parent 05394b2 commit b43b389
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 23 deletions.
1 change: 0 additions & 1 deletion Changelog.txt
Expand Up @@ -8,7 +8,6 @@ Version 5.9.4
- Fixed C _clkfreq constant in multiple enums problem
- Implemented subset of try/catch for C++
- Improved Catalina compatibility for spin2cpp
- Reverted some variable layout changes from 5.5.1
- Various improvements to the nu code backend

Version 5.9.3
Expand Down
6 changes: 3 additions & 3 deletions Test/Expect/stest170.pasm
Expand Up @@ -9,7 +9,7 @@ _setptr2
call #_nextidx
mov setptr2_tmp003_, result1
shl setptr2_tmp003_, #2
mov setptr2_tmp001_, #40
mov setptr2_tmp001_, #44
add setptr2_tmp001_, setptr2_tmp003_
mov arg01, _setptr2_c
add objptr, setptr2_tmp001_
Expand All @@ -19,12 +19,12 @@ _setptr2_ret
ret

_nextidx
add objptr, #80
add objptr, #40
rdlong result1, objptr
mov _var01, result1
add _var01, #1
wrlong _var01, objptr
sub objptr, #80
sub objptr, #40
_nextidx_ret
ret

Expand Down
61 changes: 42 additions & 19 deletions frontends/common.c
Expand Up @@ -1705,13 +1705,22 @@ DeclareOneGlobalVar(Module *P, AST *ident, AST *type, int inDat)
return;
}

#define SIZEFLAG_BYTE 0x01
#define SIZEFLAG_WORD 0x02
#define SIZEFLAG_LONG 0x04
#define SIZEFLAG_VAR 0x08
#define SIZEFLAG_OBJ 0x10
#define SIZEFLAG_DONE 0x8000
#define SIZEFLAG_ALL 0xFFFF

static int
DeclareMemberVariablesOfSize(Module *P, int basetypesize, int offset)
DeclareMemberVariablesOfSizeFlag(Module *P, int sizeRequest, int offset)
{
AST *upper;
AST *ast;
AST *curtype;
int curtypesize = basetypesize;
int curtypesize = 0;
int curSizeFlag = 0;
int isUnion = P->isUnion;
AST *varblocklist;
int oldoffset = offset;
Expand All @@ -1721,7 +1730,7 @@ DeclareMemberVariablesOfSize(Module *P, int basetypesize, int offset)
sym_flags = SYMF_PRIVATE;
}
varblocklist = P->pendingvarblock;
if (basetypesize == 0) {
if (sizeRequest & SIZEFLAG_DONE) {
P->finalvarblock = AddToList(P->finalvarblock, varblocklist);
P->pendingvarblock = NULL;
}
Expand All @@ -1737,31 +1746,39 @@ DeclareMemberVariablesOfSize(Module *P, int basetypesize, int offset)
case AST_BYTELIST:
curtype = ast_type_byte;
curtypesize = 1;
curSizeFlag = SIZEFLAG_BYTE;
idlist = ast->left;
break;
case AST_WORDLIST:
curtype = ast_type_word;
curtypesize = 2;
curSizeFlag = SIZEFLAG_WORD;
idlist = ast->left;
break;
case AST_LONGLIST:
curtype = NULL; // was ast_type_generic;
curtypesize = 4;
curSizeFlag = SIZEFLAG_LONG;
idlist = ast->left;
break;
case AST_DECLARE_VAR:
case AST_DECLARE_VAR_WEAK:
curtype = ast->left;
idlist = ast->right;
curtypesize = CheckedTypeSize(curtype); // make sure module variables are declared
if (IsClassType(curtype) || curtypesize == 0) {
curSizeFlag = SIZEFLAG_OBJ;
} else {
curSizeFlag = SIZEFLAG_VAR;
}
if (ast->d.ival) {
// variable should be private
sym_flags = SYMF_PRIVATE;
} else {
sym_flags = 0;
}
if (curtype->kind == AST_ASSIGN) {
if (basetypesize == 4 || basetypesize == 0) {
if (sizeRequest & SIZEFLAG_DONE) {
ERROR(ast, "Member variables cannot have initial values");
return offset;
}
Expand All @@ -1783,21 +1800,21 @@ DeclareMemberVariablesOfSize(Module *P, int basetypesize, int offset)
P->varsize = curtypesize;
}
}
if (basetypesize == 0) {
// round offset up to necessary alignment
// If you change this, be sure to change code for aligning
// initializers, too!
if (1 /*!gl_p2*/) { /* FIXME: what about PACKED structs */
if (curtypesize == 2) {
offset = (offset + 1) & ~1;
} else if (curtypesize >= 4) {
offset = (offset + 3) & ~3;
if (0 != (curSizeFlag & sizeRequest)) {
if (sizeRequest & (SIZEFLAG_VAR|SIZEFLAG_OBJ)) {
// round offset up to necessary alignment
// If you change this, be sure to change code for aligning
// initializers, too!
if (1 /*!gl_p2*/) { /* FIXME: what about PACKED structs */
if (curtypesize == 2) {
offset = (offset + 1) & ~1;
} else if (curtypesize >= 4) {
offset = (offset + 3) & ~3;
}
}
}
// declare all the variables
offset = EnterVars(SYM_VARIABLE, &P->objsyms, curtype, idlist, offset, P->isUnion, sym_flags);
} else if (basetypesize == curtypesize || (basetypesize == 4 && (curtypesize >= 4 || curtypesize == 0))) {
offset = EnterVars(SYM_VARIABLE, &P->objsyms, curtype, idlist, offset, P->isUnion, sym_flags);
}
}
if (curtypesize != 4 && offset != oldoffset) {
Expand Down Expand Up @@ -1880,11 +1897,17 @@ DeclareMemberVariables(Module *P)
if (P->mainLanguage == LANG_SPIN_SPIN1) {
// Spin always declares longs first, then words, then bytes
// but other languages may have other preferences
offset = DeclareMemberVariablesOfSize(P, 4, offset); // also declares >= 4
offset = DeclareMemberVariablesOfSize(P, 2, offset);
offset = DeclareMemberVariablesOfSize(P, 1, offset);
offset = DeclareMemberVariablesOfSizeFlag(P, SIZEFLAG_LONG, offset);
offset = DeclareMemberVariablesOfSizeFlag(P, SIZEFLAG_WORD, offset);
offset = DeclareMemberVariablesOfSizeFlag(P, SIZEFLAG_BYTE, offset);
offset = DeclareMemberVariablesOfSizeFlag(P, SIZEFLAG_VAR, offset);
offset = DeclareMemberVariablesOfSizeFlag(P, SIZEFLAG_OBJ|SIZEFLAG_DONE, offset);
} else if (P->mainLanguage == LANG_SPIN_SPIN2) {
// Spin always declares longs first, then words, then bytes
offset = DeclareMemberVariablesOfSizeFlag(P, SIZEFLAG_LONG|SIZEFLAG_WORD|SIZEFLAG_BYTE, offset);
offset = DeclareMemberVariablesOfSizeFlag(P, SIZEFLAG_VAR|SIZEFLAG_OBJ|SIZEFLAG_DONE, offset);
} else {
offset = DeclareMemberVariablesOfSize(P, 0, offset);
offset = DeclareMemberVariablesOfSizeFlag(P, SIZEFLAG_ALL, offset);
}
if (!P->isUnion) {
// round up to next LONG boundary
Expand Down

0 comments on commit b43b389

Please sign in to comment.