@@ -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