Skip to content

Commit 77dfda7

Browse files
committed
Avoids using stack for simple 8-bit operations and for multiplication by power of two in 8-bit
1 parent 2a82e7e commit 77dfda7

1 file changed

Lines changed: 66 additions & 34 deletions

File tree

cvbasic.c

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ enum node_type {
148148
N_AND8, N_AND16,
149149
N_EQUAL8, N_EQUAL16, N_NOTEQUAL8, N_NOTEQUAL16, N_LESS8, N_LESS16, N_LESSEQUAL8, N_LESSEQUAL16, N_GREATER8, N_GREATER16, N_GREATEREQUAL8, N_GREATEREQUAL16,
150150
N_PLUS8, N_PLUS16, N_MINUS8, N_MINUS16,
151-
N_MUL16, N_DIV16, N_MOD16,
151+
N_MUL8, N_MUL16, N_DIV16, N_MOD16,
152152
N_NEG8, N_NEG16, N_NOT8, N_NOT16,
153153
N_EXTEND8, N_REDUCE16,
154154
N_LOAD8, N_LOAD16,
@@ -358,6 +358,19 @@ void z80_2op(char *mnemonic, char *operand1, char *operand2)
358358
}
359359
}
360360

361+
/*
362+
** Check if a number is a power of two
363+
*/
364+
int is_power_of_two(int value)
365+
{
366+
if (value == 2 || value == 4 || value == 8 || value == 16
367+
|| value == 32 || value == 64 || value == 128 || value == 256
368+
|| value == 512 || value == 1024 || value == 2048 || value == 4096
369+
|| value == 8192 || value == 16384 || value == 32768)
370+
return 1;
371+
return 0;
372+
}
373+
361374
/*
362375
** Node creation.
363376
** It also optimizes common patterns of expression node trees.
@@ -384,11 +397,13 @@ struct node *node_create(enum node_type type, int value, struct node *left, stru
384397
** |
385398
** N_EXTEND8
386399
*/
387-
if ((left->type == N_PLUS16 || left->type == N_MINUS16 || left->type == N_AND16 || left->type == N_OR16 || left->type == N_XOR16) && (left->left->type == N_EXTEND8) && (left->right->type == N_NUM16)) {
400+
if ((left->type == N_PLUS16 || left->type == N_MINUS16 || left->type == N_AND16 || left->type == N_OR16 || left->type == N_XOR16 || (left->type == N_MUL16 && left->right->type == N_NUM16 && is_power_of_two(left->right->value & 0xff))) && left->left->type == N_EXTEND8 && left->right->type == N_NUM16) {
388401
if (left->type == N_PLUS16)
389402
left->type = N_PLUS8;
390403
else if (left->type == N_MINUS16)
391404
left->type = N_MINUS8;
405+
else if (left->type == N_MUL16)
406+
left->type = N_MUL8;
392407
else if (left->type == N_AND16)
393408
left->type = N_AND8;
394409
else if (left->type == N_OR16)
@@ -408,12 +423,14 @@ struct node *node_create(enum node_type type, int value, struct node *left, stru
408423
/*
409424
** Optimize expressions to avoid 16-bit operations when 8-bit are enough.
410425
*/
411-
if ((left->type == N_PLUS16 || left->type == N_MINUS16 || left->type == N_AND16 || left->type == N_OR16 || left->type == N_XOR16) && (left->right->type == N_NUM16)) {
426+
if ((left->type == N_PLUS16 || left->type == N_MINUS16 || left->type == N_AND16 || left->type == N_OR16 || left->type == N_XOR16 || (left->type == N_MUL16 && left->right->type == N_NUM16 && is_power_of_two(left->right->value & 0xff))) && (left->right->type == N_NUM16)) {
412427

413428
if (left->type == N_PLUS16)
414429
left->type = N_PLUS8;
415430
else if (left->type == N_MINUS16)
416431
left->type = N_MINUS8;
432+
else if (left->type == N_MUL16)
433+
left->type = N_MUL8;
417434
else if (left->type == N_AND16)
418435
left->type = N_AND8;
419436
else if (left->type == N_OR16)
@@ -503,10 +520,7 @@ struct node *node_create(enum node_type type, int value, struct node *left, stru
503520
return left;
504521
}
505522
if (right->type == N_NUM16) { /* Optimize power of 2 constant case */
506-
if (right->value == 2 || right->value == 4 || right->value == 8 || right->value == 16
507-
|| right->value == 32 || right->value == 64 || right->value == 128 || right->value == 256
508-
|| right->value == 512 || right->value == 1024 || right->value == 2048 || right->value == 4096
509-
|| right->value == 8192 || right->value == 16384 || right->value == 32768) {
523+
if (is_power_of_two(right->value)) {
510524
right->value--;
511525
type = N_AND16;
512526
}
@@ -1024,47 +1038,65 @@ void node_generate(struct node *node, int decision)
10241038
case N_GREATEREQUAL8:
10251039
case N_PLUS8:
10261040
case N_MINUS8:
1041+
case N_MUL8:
1042+
if (node->type == N_MUL8 && node->right->type == N_NUM8 && is_power_of_two(node->right->value)) {
1043+
int c;
1044+
1045+
node_generate(node->left, 0);
1046+
c = node->right->value;
1047+
while (c > 1) {
1048+
z80_2op("ADD", "A", "A");
1049+
c /= 2;
1050+
}
1051+
break;
1052+
}
10271053
if (node->type == N_LESSEQUAL8 || node->type == N_GREATER8) {
10281054
if (node->left->type == N_NUM8) {
10291055
node_generate(node->right, 0);
10301056
sprintf(temp, "%d", node->left->value & 0xff);
10311057
} else {
10321058
node_generate(node->left, 0);
1033-
z80_1op("PUSH", "AF");
1034-
node_generate(node->right, 0);
1035-
z80_1op("POP", "BC");
1059+
if (node->right->type == N_NUM8 || node->right->type == N_LOAD8
1060+
|| node->right->type == N_JOY1 || node->right->type == N_JOY2
1061+
|| node->right->type == N_KEY1 || node->right->type == N_KEY2
1062+
|| node->right->type == N_NTSC || node->right->type == N_MUSIC) {
1063+
z80_2op("LD", "B", "A");
1064+
node_generate(node->right, 0);
1065+
} else {
1066+
z80_1op("PUSH", "AF");
1067+
node_generate(node->right, 0);
1068+
z80_1op("POP", "BC");
1069+
}
10361070
strcpy(temp, "B");
10371071
}
1072+
} else if (node->right->type == N_NUM8) {
1073+
int c;
1074+
1075+
c = node->right->value & 0xff;
1076+
node_generate(node->left, 0);
1077+
if (node->type == N_PLUS8 && c == 1) {
1078+
z80_1op("INC", "A");
1079+
break;
1080+
}
1081+
if (node->type == N_MINUS8 && c == 1) {
1082+
z80_1op("DEC", "A");
1083+
break;
1084+
}
1085+
sprintf(temp, "%d", c);
10381086
} else {
1039-
if (node->right->type == N_NUM8) {
1040-
int c;
1041-
1042-
c = node->right->value & 0xff;
1087+
node_generate(node->right, 0);
1088+
if (node->left->type == N_NUM8 || node->left->type == N_LOAD8
1089+
|| node->left->type == N_JOY1 || node->left->type == N_JOY2
1090+
|| node->left->type == N_KEY1 || node->left->type == N_KEY2
1091+
|| node->left->type == N_NTSC || node->left->type == N_MUSIC) {
1092+
z80_2op("LD", "B", "A");
10431093
node_generate(node->left, 0);
1044-
if (node->type == N_OR8 && c == 0)
1045-
break;
1046-
if (node->type == N_AND8 && c == 255)
1047-
break;
1048-
if (node->type == N_PLUS8 && c == 0)
1049-
break;
1050-
if (node->type == N_MINUS8 && c == 0)
1051-
break;
1052-
if (node->type == N_PLUS8 && c == 1) {
1053-
z80_1op("INC", "A");
1054-
break;
1055-
}
1056-
if (node->type == N_MINUS8 && c == 1) {
1057-
z80_1op("DEC", "A");
1058-
break;
1059-
}
1060-
sprintf(temp, "%d", c);
10611094
} else {
1062-
node_generate(node->right, 0);
10631095
z80_1op("PUSH", "AF");
10641096
node_generate(node->left, 0);
10651097
z80_1op("POP", "BC");
1066-
strcpy(temp, "B");
10671098
}
1099+
strcpy(temp, "B");
10681100
}
10691101
if (node->type == N_OR8) {
10701102
z80_1op("OR", temp);
@@ -1390,7 +1422,7 @@ void node_generate(struct node *node, int decision)
13901422
explore = node->right;
13911423
else
13921424
explore = NULL;
1393-
if (explore != NULL && (explore->value == 0 || explore->value == 1 || explore->value == 2 || explore->value == 4 || explore->value == 8 || explore->value == 16 || explore->value == 32 || explore->value == 64 || explore->value == 128 || explore->value == 256 || explore->value == 512 || explore->value == 1024 || explore->value == 2048 || explore->value == 4096 || explore->value == 8192 || explore->value == 16384 || explore->value == 32768)) {
1425+
if (explore != NULL && (explore->value == 0 || explore->value == 1 || is_power_of_two(explore->value))) {
13941426
int c = explore->value;
13951427

13961428
if (c == 0) {

0 commit comments

Comments
 (0)