code: plan9front

Download patch

ref: 74c1f4730b548c3499e59ac0c2f2aadfcd7727c5
parent: 7a503757b1251c2746df7bdcd891814c1518cc28
author: Jacob Moody <moody@posixcafe.org>
date: Sat Jan 6 22:04:35 EST 2024

6?, 8?, libc: add JMPF instruction

In 6? and 8? JMP works a bit uniquely,
when passed a function name it always encodes
as a JMP* instead of a JMP. This means

JMP myfunc(SB)

always assume that myfunc is a function pointer, not
a function itself. The new JMPF instead has the same
semantics as CALL and matches B and JMP in other
assemblers. This allows for a small optimization in
our 386 and amd64 entrypoint by avoiding a jump between
_main and _callmain.

--- a/sys/src/cmd/6a/lex.c
+++ b/sys/src/cmd/6a/lex.c
@@ -433,6 +433,7 @@
 
 	"JCXZ",		LTYPER,	AJCXZ,
 	"JMP",		LTYPEC,	AJMP,
+	"JMPF",		LTYPEC, AJMPF,
 	"LAHF",		LTYPE0,	ALAHF,
 	"LARL",		LTYPE3,	ALARL,
 	"LARW",		LTYPE3,	ALARW,
--- a/sys/src/cmd/6c/6.out.h
+++ b/sys/src/cmd/6c/6.out.h
@@ -713,6 +713,8 @@
 	ADPPD,
 	ADPPS,
 
+	AJMPF,
+
 	ALAST
 };
 
--- a/sys/src/cmd/6l/l.h
+++ b/sys/src/cmd/6l/l.h
@@ -170,6 +170,7 @@
 	Zilo_m,
 	Ziqo_m,
 	Zjmp,
+	Zjmpf,
 	Zloop,
 	Zo_iw,
 	Zm_o,
--- a/sys/src/cmd/6l/optab.c
+++ b/sys/src/cmd/6l/optab.c
@@ -295,6 +295,11 @@
 	Ynone,	Ybr,	Zjmp,	1,
 	0
 };
+uchar	yjmpf[] =
+{
+	Ynone,	Ybr,	Zjmpf,	1,
+	0
+};
 
 uchar	yfmvd[] =
 {
@@ -717,6 +722,7 @@
 	{ AJLT,		yjcond,	Px, 0x7c,0x8c },
 	{ AJMI,		yjcond,	Px, 0x78,0x88 },
 	{ AJMP,		yjmp,	Px, 0xff,(04),0xeb,0xe9 },
+	{ AJMPF,	yjmpf,	Px, 0xe9  },
 	{ AJNE,		yjcond,	Px, 0x75,0x85 },
 	{ AJOC,		yjcond,	Px, 0x71,0x81,(00) },
 	{ AJOS,		yjcond,	Px, 0x70,0x80,(00) },
--- a/sys/src/cmd/6l/pass.c
+++ b/sys/src/cmd/6l/pass.c
@@ -142,7 +142,7 @@
 		return;
 	if(p->as == ATEXT)
 		curtext = p;
-	if(p->as == AJMP)
+	if(p->as == AJMP || p->as == AJMPF)
 	if((q = p->pcond) != P) {
 		p->mark = 1;
 		p = q;
@@ -319,7 +319,7 @@
 	for(p = firstp; p != P; p = p->link) {
 		if(p->as == ATEXT)
 			curtext = p;
-		if(p->as == ACALL || p->as == ARET) {
+		if(p->as == ACALL || p->as == ARET || p->as == AJMPF) {
 			s = p->to.sym;
 			if(s) {
 				if(debug['c'])
--- a/sys/src/cmd/6l/span.c
+++ b/sys/src/cmd/6l/span.c
@@ -1360,6 +1360,7 @@
 		}
 		break;
 
+	case Zjmpf:
 	case Zcall:
 		q = p->pcond;
 		if(q) {
--- a/sys/src/cmd/8a/lex.c
+++ b/sys/src/cmd/8a/lex.c
@@ -372,6 +372,7 @@
 
 	"JCXZ",		LTYPER,	AJCXZ,
 	"JMP",		LTYPEC,	AJMP,
+	"JMPF",		LTYPEC,	AJMPF,
 	"LAHF",		LTYPE0,	ALAHF,
 	"LARL",		LTYPE3,	ALARL,
 	"LARW",		LTYPE3,	ALARW,
--- a/sys/src/cmd/8c/8.out.h
+++ b/sys/src/cmd/8c/8.out.h
@@ -585,6 +585,8 @@
 	API2FW,
 	API2FL,
 
+	AJMPF,
+
 	/* add new operations here. nowhere else. here. */
 	ALAST
 };
--- a/sys/src/cmd/8l/l.h
+++ b/sys/src/cmd/8l/l.h
@@ -158,6 +158,7 @@
 	Zil_rp,
 	Zilo_m,
 	Zjmp,
+	Zjmpf,
 	Zloop,
 	Zm_o,
 	Zm_r,
--- a/sys/src/cmd/8l/optab.c
+++ b/sys/src/cmd/8l/optab.c
@@ -240,6 +240,11 @@
 	Ynone,	Ybr,	Zjmp,	1,
 	0
 };
+uchar	yjmpf[] =
+{
+	Ynone,	Ybr,	Zjmp,	1,
+	0
+};
 
 uchar	yfmvd[] =
 {
@@ -563,6 +568,7 @@
 	{ AJLT,		yjcond,	Px, 0x7c,0x8c },
 	{ AJMI,		yjcond,	Px, 0x78,0x88 },
 	{ AJMP,		yjmp,	Px, 0xff,(04),0xeb,0xe9 },
+	{ AJMPF,	yjmpf,	Px, 0xe9 },
 	{ AJNE,		yjcond,	Px, 0x75,0x85 },
 	{ AJOC,		yjcond,	Px, 0x71,0x81,(00) },
 	{ AJOS,		yjcond,	Px, 0x70,0x80,(00) },
--- a/sys/src/cmd/8l/pass.c
+++ b/sys/src/cmd/8l/pass.c
@@ -136,7 +136,7 @@
 		return;
 	if(p->as == ATEXT)
 		curtext = p;
-	if(p->as == AJMP)
+	if(p->as == AJMP || p->as == AJMPF)
 	if((q = p->pcond) != P) {
 		p->mark = 1;
 		p = q;
@@ -303,7 +303,7 @@
 	for(p = firstp; p != P; p = p->link) {
 		if(p->as == ATEXT)
 			curtext = p;
-		if(p->as == ACALL || p->as == ARET) {
+		if(p->as == ACALL || p->as == ARET || p->as == AJMPF) {
 			s = p->to.sym;
 			if(s) {
 				if(debug['c'])
--- a/sys/src/cmd/8l/span.c
+++ b/sys/src/cmd/8l/span.c
@@ -1151,6 +1151,7 @@
 		}
 		break;
 
+	case Zjmpf:
 	case Zcall:
 		q = p->pcond;
 		if(q) {
--- a/sys/src/libc/386/main9.s
+++ b/sys/src/libc/386/main9.s
@@ -3,5 +3,4 @@
 	MOVL	$main(SB), AX
 	PUSHL	AX
 	PUSHL	$0
-	MOVL	$_callmain(SB), AX
-	JMP*	AX
+	JMPF	_callmain(SB)
--- a/sys/src/libc/386/main9p.s
+++ b/sys/src/libc/386/main9p.s
@@ -3,8 +3,7 @@
 	MOVL	$_profmain(SB), AX
 	PUSHL	AX
 	PUSHL	$0
-	MOVL	$_callmain(SB), AX
-	JMP*	AX
+	JMPF	_callmain(SB)
 	MOVL	$_profin(SB), AX	/* force loading of profile */
 
 TEXT	_saveret(SB), 1, $0
--- a/sys/src/libc/amd64/main9.s
+++ b/sys/src/libc/amd64/main9.s
@@ -3,5 +3,4 @@
 	MOVQ	$main(SB), RARG
 	PUSHQ	RARG
 	PUSHQ	$0
-	MOVQ	$_callmain(SB), AX
-	JMP*	AX
+	JMPF	_callmain(SB)
--- a/sys/src/libc/amd64/main9p.s
+++ b/sys/src/libc/amd64/main9p.s
@@ -3,8 +3,7 @@
 	MOVQ	$_profmain(SB), RARG
 	PUSHQ	RARG
 	PUSHQ	$0
-	MOVQ	$_callmain(SB), AX
-	JMP*	AX
+	JMPF	_callmain(SB)
 
 	MOVQ	$_profin(SB), AX	/* force loading of profile */