Skip to content

Commit

Permalink
fixed use of ++ and -- in expressions involving 64 bit quantities
Browse files Browse the repository at this point in the history
  • Loading branch information
totalspectrum committed Mar 10, 2024
1 parent 689b18f commit 4066117
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 86 deletions.
1 change: 1 addition & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Version 6.9.0
- Added new optimization to merge duplicate functions (only at -O2, and so far only works for small functions)
- Extract side effects in more cases to avoid errors with ++,-- in complex expressions
- Fixed some nucode compilation problems with the C test suite
- Fixed failure to allocate memory for local variables in some cases
- Fixed incorrect removal of some functions that were not completely inlined
Expand Down
5 changes: 1 addition & 4 deletions Test/Expect/stest121.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ dat
entry

_demo
mov _var01, arg01
mov _var02, arg02
mov _var03, arg03
mov result1, _var02
mov result1, arg02
_demo_ret
ret

Expand Down
6 changes: 2 additions & 4 deletions Test/Expect/stest155.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ entry

_ident
mov result1, arg01
mov _var02, arg02
mov result2, _var02
mov result2, arg02
_ident_ret
ret

_test
mov result1, #0
mov _var02, #0
mov result2, _var02
mov result2, #0
wrlong result1, ptr__dat__
add ptr__dat__, #4
wrlong result2, ptr__dat__
Expand Down
15 changes: 3 additions & 12 deletions Test/Expect/stest191.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,19 @@ dat
entry

_fetch
mov _var01, arg01
mov _var02, arg02
mov result1, _var02
mov result1, arg02
_fetch_ret
ret

_fetch2
mov _var02, arg02
mov arg02, _var02
mov _var03, arg01
mov _var04, arg02
mov result1, _var04
mov result1, arg02
_fetch2_ret
ret

_fetchu
rdlong _var01, ptr__dat__
add ptr__dat__, #4
rdlong arg02, ptr__dat__
rdlong result1, ptr__dat__
sub ptr__dat__, #4
mov _var02, arg02
mov result1, _var02
_fetchu_ret
ret

Expand Down
7 changes: 2 additions & 5 deletions Test/Expect/stest229.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ dat
entry

_show
mov _var01, arg01
mov _var02, arg02
mov _var03, arg03
mov outa, _var02
mov outb, _var03
mov outa, arg02
mov outb, arg03
_show_ret
ret

Expand Down
9 changes: 3 additions & 6 deletions Test/Expect/stest230.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ dat
entry

_show
mov _var01, arg01
mov _var02, arg02
mov _var03, arg03
mov outa, _var01
mov outb, _var02
mov ina, _var03
mov outa, arg01
mov outb, arg02
mov ina, arg03
_show_ret
ret

Expand Down
4 changes: 1 addition & 3 deletions Test/Expect/stest233.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ dat
entry

_demo
mov _var01, arg01
mov _var02, arg02
mov result1, _var02
mov result1, arg02
_demo_ret
ret

Expand Down
3 changes: 1 addition & 2 deletions Test/Expect/stest249.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ entry

_insertstr
mov result1, arg01
mov _var02, arg02
add result1, arg03
mov result2, _var02
mov result2, arg02
_insertstr_ret
ret

Expand Down
28 changes: 10 additions & 18 deletions Test/Expect/stest258.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,18 @@ dat
entry

_allbits
mov _var01, #0
mov _var02, #0
mov result1, #0
mov result2, #0
LR__0001
cmps arg02, #1 wc
if_b jmp #LR__0002
mov result1, _var01
mov result2, _var02
rdlong arg03, arg01
add arg01, #4
rdlong arg04, arg01
or result1, arg03
or result2, arg04
mov _var01, result1
mov _var02, result2
add arg01, #4
sub arg02, #1
jmp #LR__0001
LR__0002
mov result2, _var02
mov result1, _var01
if_ae rdlong arg03, arg01
if_ae add arg01, #4
if_ae rdlong arg04, arg01
if_ae or result1, arg03
if_ae or result2, arg04
if_ae add arg01, #4
if_ae sub arg02, #1
if_ae jmp #LR__0001
_allbits_ret
ret

Expand Down
5 changes: 1 addition & 4 deletions Test/Expect/stest275.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,10 @@ _getitA
rdlong _var05, arg01
rdlong result1, _var05
add _var05, #4
rdlong _var02, _var05
rdlong result2, _var05
rdlong _var06, arg01
add _var06, #8
wrlong _var06, arg01
mov _var05, _var02
mov _var04, _var05
mov result2, _var04
_getitA_ret
ret

Expand Down
13 changes: 4 additions & 9 deletions Test/Expect/stest278.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,14 @@ _bump1
add ptr__dat__, #4
rdlong arg03, ptr__dat__
mov result1, arg04
mov _var02, arg03
mov result2, arg03
sub ptr__dat__, #4
add arg04, #1 wc
addx arg03, #0
wrlong arg04, ptr__dat__
add ptr__dat__, #4
wrlong arg03, ptr__dat__
sub ptr__dat__, #4
mov result2, _var02
mov _var04, result2
mov result2, _var04
_bump1_ret
ret

Expand All @@ -40,16 +37,14 @@ _bump2_ret
_bump3
rdlong result1, ptr__dat__
add ptr__dat__, #4
rdlong arg04, ptr__dat__
rdlong result2, ptr__dat__
sub ptr__dat__, #4
add result1, #1 wc
addx arg04, #0
addx result2, #0
wrlong result1, ptr__dat__
add ptr__dat__, #4
wrlong arg04, ptr__dat__
wrlong result2, ptr__dat__
sub ptr__dat__, #4
mov _var02, arg04
mov result2, _var02
_bump3_ret
ret

Expand Down
4 changes: 1 addition & 3 deletions Test/Expect/stest286.pasm
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ dat
entry

_get_high
mov _var01, arg01
mov _var02, arg02
mov result1, _var02
mov result1, arg02
_get_high_ret
ret

Expand Down
58 changes: 50 additions & 8 deletions backends/asm/outasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,45 @@ OffsetName(const char *basename, unsigned long offset)
return tempname;
}

static struct flexbuf subRegVars;

static void AddSubRegister(Operand *sub, Operand *reg, unsigned long offset)
{
flexbuf_addmem(&subRegVars, (const char *)&reg, sizeof(reg));
}

static Operand *FindSubRegister(Operand *reg, unsigned long offset)
{
size_t siz = flexbuf_curlen(&subRegVars) / sizeof(reg);
size_t i;
Operand **ptr;
Operand *sub;

ptr = (Operand **)flexbuf_peek(&subRegVars);
offset /= LONG_SIZE;

for (i = 0; i < siz; i++) {
sub = ptr[i];
if (sub->name == (char *)reg && sub->val == offset)
return sub;
}
return NULL;
}

Operand *
SubRegister(Operand *reg, unsigned long offset)
{
Operand *sub = NewOperand(REG_SUBREG, (char *)reg, 0);
if (reg->size < offset) {
reg->size = offset;
Operand *sub = FindSubRegister(reg, offset);

if (!sub) {
sub = NewOperand(REG_SUBREG, (char *)reg, 0);
if (reg->size < offset) {
reg->size = offset;
}
sub->val = offset / LONG_SIZE;
AddSubRegister(sub, reg, offset / LONG_SIZE);
}
reg->used++;
sub->val = offset / LONG_SIZE;
return sub;
}

Expand Down Expand Up @@ -1755,12 +1785,13 @@ RenameSubregs(IRList *irl, Operand *base, int numlocals, int isLeaf)
*/

static int
RenameLocalRegs(IRList *irl, bool isLeaf)
doRenameLocalRegs(Function *func, bool isLeaf)
{
IR *ir;
Operand *replace = NULL;
int numlocals = 0;

IRList *irl = FuncIRL(func);

/* first, look for any subregisters; if found, rename those
* in a way that guarantees the arrays stay in order
*/
Expand All @@ -1786,6 +1817,17 @@ RenameLocalRegs(IRList *irl, bool isLeaf)
return numlocals;
}

static int
RenameLocalRegs(Function *func, bool isLeaf)
{
IRList *irl = FuncIRL(func);
if (isLeaf) {
doRenameLocalRegs(func, true);
OptimizeIRLocal(irl, func);
}
return doRenameLocalRegs(func, isLeaf);
}

static bool
NeedToSaveLocals(Function *func)
{
Expand Down Expand Up @@ -1912,7 +1954,7 @@ static void EmitFunctionHeader(IRList *irl, Function *func)
needFrame = NeedFramePointer(func);
if (needFrame == FRAME_YES || needFrame == FRAME_MAYBE) {
if (NeedToSaveLocals(func)) {
n = RenameLocalRegs(FuncIRL(func), false);
n = RenameLocalRegs(func, false);
} else {
MarkUsedAsmVars(FuncIRL(func));
}
Expand All @@ -1938,7 +1980,7 @@ static void EmitFunctionHeader(IRList *irl, Function *func)
}
}
if (IS_LEAF(func)) {
RenameLocalRegs(FuncIRL(func), true);
RenameLocalRegs(func, true);
}
if (ANY_VARS_ON_STACK(func)) {
int localsize;
Expand Down
26 changes: 18 additions & 8 deletions frontends/hltransform.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Spin to C/C++ converter
* Copyright 2011-2023 Total Spectrum Software Inc.
* Copyright 2011-2024 Total Spectrum Software Inc.
* See the file COPYING for terms of use
*
* various high level transformations that should take
Expand Down Expand Up @@ -305,8 +305,10 @@ doSimplifyAssignments(AST **astptr, int insertCasts, int atTopLevel)
}
if (ast->kind == AST_ASSIGN) {
int op = ast->d.ival;
int size;
lhs = ast->left;
rhs = ast->right;
size = TypeSize(ExprType(lhs));
if (IsConstExpr(lhs)) {
if (IsIdentifier(lhs)) {
// check for CON := x
Expand All @@ -325,19 +327,21 @@ doSimplifyAssignments(AST **astptr, int insertCasts, int atTopLevel)
return;
}
}
else if (op && op != K_ASSIGN )
else if (op && (op != K_ASSIGN || size > LONG_SIZE) )
{
bool change = false;
AstReportAs(ast, &saveinfo);
// if B has side effects,
// transform A op= B
// into tmp = B, A op= tmp
// then if A has side effects, further decompose
// those so eventually we can get A = A' op tmp
if (rhs && ExprHasSideEffects(rhs) && !TraditionalBytecodeOutput()) {
AST *typ = ExprType(rhs);
AST *temp = AstTempLocalVariable("_temp_", typ);
preseq = AstAssign(temp, rhs);
rhs = temp;
AST *oldrhs = rhs;
rhs = ExtractSideEffects(rhs, &preseq);
if (! (rhs == oldrhs && preseq == NULL) ) {
change = true;
}
}
if ((ExprHasSideEffects(lhs) || IsBoolOp(op)) && !TraditionalBytecodeOutput()) {
if (curfunc && IsSpinLang(curfunc->language) && rhs && !IsConstExpr(rhs)) {
Expand All @@ -351,11 +355,18 @@ doSimplifyAssignments(AST **astptr, int insertCasts, int atTopLevel)
preseq = p2;
}
rhs = temp;
change = true;
}
AST *oldlhs = lhs;
lhs = ExtractSideEffects(lhs, &preseq);
if (lhs != oldlhs) {
change = true;
}
}
if (op == 0 || op == K_ASSIGN) {
ast = AstAssign(lhs, rhs);
if (change) {
ast = AstAssign(lhs, rhs);
}
} else {
if (rhs) {
ast = AstAssign(lhs, AstOperator(op, DupAST(lhs), rhs));
Expand All @@ -371,7 +382,6 @@ doSimplifyAssignments(AST **astptr, int insertCasts, int atTopLevel)
lhs = ast->left;
rhs = ast->right;
}

// check for special cases like local.byte[N] := X where N is a constant
if (lhs && lhs->kind == AST_ARRAYREF) {
AST *newexpr = CheckSimpleArrayref(lhs);
Expand Down

0 comments on commit 4066117

Please sign in to comment.