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.
This commit is contained in:
Jacob Moody 2024-01-07 03:04:35 +00:00
parent 7a503757b1
commit 74c1f4730b
16 changed files with 30 additions and 12 deletions

View file

@ -433,6 +433,7 @@ struct
"JCXZ", LTYPER, AJCXZ,
"JMP", LTYPEC, AJMP,
"JMPF", LTYPEC, AJMPF,
"LAHF", LTYPE0, ALAHF,
"LARL", LTYPE3, ALARL,
"LARW", LTYPE3, ALARW,

View file

@ -713,6 +713,8 @@ enum as
ADPPD,
ADPPS,
AJMPF,
ALAST
};

View file

@ -170,6 +170,7 @@ enum
Zilo_m,
Ziqo_m,
Zjmp,
Zjmpf,
Zloop,
Zo_iw,
Zm_o,

View file

@ -295,6 +295,11 @@ uchar yjmp[] =
Ynone, Ybr, Zjmp, 1,
0
};
uchar yjmpf[] =
{
Ynone, Ybr, Zjmpf, 1,
0
};
uchar yfmvd[] =
{
@ -717,6 +722,7 @@ Optab optab[] =
{ 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) },

View file

@ -142,7 +142,7 @@ loop:
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 @@ patch(void)
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'])

View file

@ -1360,6 +1360,7 @@ found:
}
break;
case Zjmpf:
case Zcall:
q = p->pcond;
if(q) {

View file

@ -372,6 +372,7 @@ struct
"JCXZ", LTYPER, AJCXZ,
"JMP", LTYPEC, AJMP,
"JMPF", LTYPEC, AJMPF,
"LAHF", LTYPE0, ALAHF,
"LARL", LTYPE3, ALARL,
"LARW", LTYPE3, ALARW,

View file

@ -585,6 +585,8 @@ enum as
API2FW,
API2FL,
AJMPF,
/* add new operations here. nowhere else. here. */
ALAST
};

View file

@ -158,6 +158,7 @@ enum
Zil_rp,
Zilo_m,
Zjmp,
Zjmpf,
Zloop,
Zm_o,
Zm_r,

View file

@ -240,6 +240,11 @@ uchar yjmp[] =
Ynone, Ybr, Zjmp, 1,
0
};
uchar yjmpf[] =
{
Ynone, Ybr, Zjmp, 1,
0
};
uchar yfmvd[] =
{
@ -563,6 +568,7 @@ Optab optab[] =
{ 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) },

View file

@ -136,7 +136,7 @@ loop:
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 @@ patch(void)
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'])

View file

@ -1151,6 +1151,7 @@ found:
}
break;
case Zjmpf:
case Zcall:
q = p->pcond;
if(q) {

View file

@ -3,5 +3,4 @@ TEXT _main(SB), 1, $0
MOVL $main(SB), AX
PUSHL AX
PUSHL $0
MOVL $_callmain(SB), AX
JMP* AX
JMPF _callmain(SB)

View file

@ -3,8 +3,7 @@ TEXT _mainp(SB), 1, $0
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

View file

@ -3,5 +3,4 @@ TEXT _main(SB), 1, $0
MOVQ $main(SB), RARG
PUSHQ RARG
PUSHQ $0
MOVQ $_callmain(SB), AX
JMP* AX
JMPF _callmain(SB)

View file

@ -3,8 +3,7 @@ TEXT _mainp(SB), 1, $0
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 */