Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

be-codegen-6800.c Optimizes addition and subtraction with signed/unsigned char. #167

Open
zu2 opened this issue Nov 18, 2024 · 2 comments
Open
Labels
enhancement New feature or request

Comments

@zu2
Copy link
Contributor

zu2 commented Nov 18, 2024

Currently, addition with signed/unsigned char pushes the augend onto the stack, sign-extends the addend, and then calls a helper function.

This patch provides shorter code.

--- ../Fuzix-Compiler-Kit/be-codegen-6800.c	2024-11-18 09:16:57
+++ be-codegen-6800.c	2024-11-18 21:02:24
@@ -514,6 +514,20 @@
 			invalidate_d();
 			add_d_const(v);
 			return 1;
+		}
+		if (s == 2 && r->op == T_CAST && (r->type&~UNSIGNED) == CSHORT && is_simple(r->right)) {
+			if (r->right->type == UCHAR) {
+				op8_on_node(r->right, "add", 0);
+				puts("\tadca #0");
+				return 1;
+			}else if (r->right->type == CCHAR) {
+				unsigned l = ++label;
+				write_uni_op(r->right, "tst", 0);
+				printf("\tbpl X%u\n\tdeca\nX%u:\n",l,l);
+				op8_on_node(r->right, "add", 0);
+				puts("\tadca #0");
+				return 1;
+			}
 		}
 		return write_opd(r, "add", "adc", 0);
 	case T_MINUS:
@@ -527,6 +541,20 @@
 			if (s == 1) {
 				add_b_const(-r->value);
 				b_val -= r->value;
+				return 1;
+			}
+		}
+		if (s == 2 && r->op == T_CAST && (r->type&~UNSIGNED) == CSHORT && is_simple(r->right)) {
+			if (r->right->type == UCHAR) {
+				op8_on_node(r->right, "sub", 0);
+				puts("\tsbca #0");
+				return 1;
+			}else if (r->right->type == CCHAR) {
+				unsigned l = ++label;
+				write_uni_op(r->right, "tst", 0);
+				printf("\tbpl X%u\n\tinca\nX%u:\n",l,l);
+				op8_on_node(r->right, "sub", 0);
+				puts("\tsbca #0");
 				return 1;
 			}
 		}

the patch pass this test program.

#include	"cprintf.c"

int
main(int argc,char **argv)
{
	signed char c1, c2;
	int	i1,i2;

	for(i1=-128; i1<=127; i1++){
		for(i2=-128; i2<=127; i2++){
			c1 = i1;
			c2 = i2;
			if(c1+c2 != i1+i2){
				cprintf("%d+%d=%d (!=%d)\n",i1,i2,c1+c2,i1+i2);
				return 1;
			}
			if(c1-c2 != i1-i2){
				cprintf("%d+%d=%d (!=%d)\n",i1,i2,c1-c2,i1-i2);
				return 2;
			}
		}
	}

	return 0;
}

before

        ldb 0,x
        clra
        asrb
        rolb
        sbca #0
        pshb
        psha
        ldb 1,x
        clra
        asrb
        rolb
        sbca #0
        jsr __plus

after.

        ldb 0,x
        clra
        asrb
        rolb
        sbca #0
        tst 1,x
        bpl X1
        deca
X1:
        addb 1,x
        adca #0

This patch does not shorten the form *p - *q as memcmp uses. I am looking for a way to do this.

@zu2 zu2 changed the title be-codegen-6800.c Optimizes addition and subtraction with signed char. be-codegen-6800.c Optimizes addition and subtraction with signed/unsigned char. Nov 18, 2024
@EtchedPixels EtchedPixels added the enhancement New feature or request label Nov 18, 2024
@zu2
Copy link
Contributor Author

zu2 commented Nov 19, 2024

In the signed case, this results in better code. use gen_shortcut.

@@ -1393,6 +1428,38 @@
 		return do_xeqop(n, "xoreq");
 	case T_HATEQ:
 		return do_xeqop(n, "xhateq");
+	case T_PLUS:
+		if (s==2 && n->type==CSHORT
+		&&  r->op == T_CAST && r->type == CSHORT
+	    &&  l->op == T_CAST && l->type == CSHORT
+		&&  r->right->type == CCHAR
+		&&  l->right->type == CCHAR ){
+			if (is_simple(r->right)){
+				codegen_lr(l->right);
+				puts("\tclra");
+                		op8_on_node(r->right, "add", 0);
+				printf("\tbge X%d\n\tdeca\n",++label);
+				printf("X%d:\n",label);
+				return 1;
+			}
+		}
+		return 0;
+	case T_MINUS:
+		if (s==2 && n->type==CSHORT
+		&&  r->op == T_CAST && r->type == CSHORT
+	    &&  l->op == T_CAST && l->type == CSHORT
+		&&  r->right->type == CCHAR
+		&&  l->right->type == CCHAR ){
+			if (is_simple(r->right)){
+				codegen_lr(l->right);
+				puts("\tclra");
+                		op8_on_node(r->right, "sub", 0);
+				printf("\tbge X%d\n\tdeca\n",++label);
+				printf("X%d:\n",label);
+				return 1;
+			}
+		}
+		return 0;

@EtchedPixels
Copy link
Owner

Will defer until after we have byte conversions done and can see what is actually needed for best results

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants