Add csa 8, csb 8 for i386, m68020.

This allows `long long x; switch (x) {...}` in C.  Add test in C.

This adapts the code for csa 8 and csb 8 from the existing code for
csa 4 and csb 4, for both i386 and m68020.
This commit is contained in:
George Koehler 2019-09-27 12:15:10 -04:00
parent d6413c1a11
commit 0b0c3d5b60
10 changed files with 238 additions and 3 deletions

View file

@ -1,7 +1,7 @@
for _, plat in ipairs(vars.plats) do
acklibrary {
name = "lib_"..plat,
srcs = { "./*.s" }, -- divrem8.s
srcs = { "./*.s" }, -- csb8.s
vars = { plat = plat },
}
end

35
mach/i386/libem/csa8.s Normal file
View file

@ -0,0 +1,35 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .csa8
.sect .text
.csa8:
! ebx, descriptor address
! edx:eax, index
mov ecx,(ebx) ! default
sub eax,4(ebx)
sbb edx,8(ebx) ! index - lower bound
push edx
push eax
mov eax,12(ebx)
mov edx,16(ebx) ! upper bound - lower bound
sub eax,(esp)
sbb edx,4(esp) ! upper bound - index
pop eax
pop edx
jb 1f ! jump if upper bound < index
! assuming edx:eax < 2**30
mov ebx,20(ebx)(eax*4)
test ebx,ebx
jnz 2f
1:
mov ebx,ecx
test ebx,ebx
jnz 2f
.extern ECASE
.extern .fat
mov eax,ECASE
push eax
jmp .fat
2:
jmp ebx

39
mach/i386/libem/csb8.s Normal file
View file

@ -0,0 +1,39 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .csb8
.sect .text
.csb8:
! ebx, descriptor address
! edx:eax, index
push esi
push edi
push (ebx) ! default
mov ecx,4(ebx) ! entry count (assuming < 2**32)
1:
add ebx,12
dec ecx
jl 4f
mov esi,0(ebx)
mov edi,4(ebx) ! descriptor's index
sub esi,eax
sbb edi,edx
or esi,edi
jne 1b
pop edx ! drop default
mov ebx,8(ebx)
2:
pop edi
pop esi
test ebx,ebx
jnz 3f
.extern ECASE
.extern .fat
mov eax,ECASE
push eax
jmp .fat
3:
jmp ebx
4:
pop ebx ! default
jmp 2b

View file

@ -3074,6 +3074,11 @@ with BXREG ACC
kills ALL
gen jmp {label, ".csa4"}
pat csa $1==8
with BXREG ACC DXREG
kills ALL
gen jmp {label, ".csa8"}
pat csa !defined($1)
with rm-BXREG-ACC BXREG ACC
kills ALL
@ -3086,6 +3091,11 @@ with BXREG ACC
kills ALL
gen jmp {label, ".csb4"}
pat csb $1==8
with BXREG ACC DXREG
kills ALL
gen jmp {label, ".csb8"}
pat csb !defined($1)
with rm-BXREG-ACC BXREG ACC
gen cmp %1,{ANYCON,4}

View file

@ -2,7 +2,7 @@ for _, plat in ipairs(vars.plats) do
acklibrary {
name = "lib_"..plat,
srcs = {
"./*.s", -- added divrem8.s
"./*.s", -- csb8.s
"./*.c"
},
vars = { plat = plat },

39
mach/m68020/libem/csa8.s Normal file
View file

@ -0,0 +1,39 @@
.define .csa8
.sect .text
.sect .rom
.sect .data
.sect .bss
ECASE=20
.sect .text
.csa8:
! jump table address in a0
! index in (sp)
move.l (a0)+, a1 ! default address
move.l (sp)+, d0
move.l (sp)+, d1 ! index
move.l (a0)+, d2
sub.l (a0)+, d1
subx.l d2, d0 ! index - lower bound in d0:d1
move.l d1, a2
move.l (a0)+, d2
move.l (a0)+, d1 ! upper - lower bound
sub.l a2, d1
subx.l d0, d2 ! upper - index
bcs 1f
move.l a2, d1
! assuming d0:d1 < 65536
move.l (a0,d1.l*4), d1 ! jump address
beq 1f
move.l d1,a1
jmp (a1)
1:
move.l a1, d0
beq 2f
jmp (a1) ! jump to specified address
2:
move.l #ECASE, -(sp)
jmp (.fatal)
.align 2

39
mach/m68020/libem/csb8.s Normal file
View file

@ -0,0 +1,39 @@
.define .csb8
.sect .text
.sect .rom
.sect .data
.sect .bss
ECASE=20
.sect .text
.csb8:
! case descriptor in a0
! index in (sp)
move.l (a0)+, a1 ! default jump address
move.l (sp)+, d2
move.l (sp), a2 ! index in d2:a2
move.l d7, (sp)
add.l #4, a0
move.l (a0)+, d1 ! # entries (assuming <= 65536)
beq 3f
sub.l #1, d1
1:
move.l (a0)+, d0
move.l (a0)+, d7 ! descriptor's index in d0:d7
add.l #4, a0
sub.l a2, d7
subx.l d2, d0 ! descriptor's index - our index
dbeq d1, 1b
bne 3f
move.l (-4,a0), a1 ! jump address
3:
move.l (sp)+, d7 ! caller's d7
move.l a1, d0
beq 4f
jmp (a1)
4:
move.l #ECASE, -(sp)
jmp (.fatal)
.align 2

View file

@ -6057,6 +6057,11 @@ with any4 D_REG4+DLOCAL+const4+absolute4 STACK
move %2,dl0
jmp {absolute4, ".csa4"}
pat csa $1==8
with any4 STACK
gen move %1,a0
jmp {absolute4, ".csa8"}
#if WORD_SIZE==2
pat csb $1==2
#if TBL68020
@ -6079,6 +6084,11 @@ with any4 D_REG4+DLOCAL+const4+absolute4 STACK
move %2,dl0
jmp {absolute4, ".csb4"}
pat csb $1==8
with any4 STACK
gen move %1,a0
jmp {absolute4, ".csb8"}
pat dch leaving loi 4
#if WORD_SIZE==2

View file

@ -1,10 +1,11 @@
include("plat/build.lua")
definerule("plat_testsuite",
{
plat = { type="string" },
method = { type="string" },
-- added long-long/lldivrem_e.c
-- added long-long/llswitch_e.c
sets = { type="table", default={"core", "b", "bugs", "m2", "floats", "long-long"}},
skipsets = { type="table", default={}},
tests = { type="targets", default={} },

View file

@ -0,0 +1,62 @@
#include "test.h"
long long a = -719560752603LL;
long long b = -319239774717LL;
long long c = 100200300401LL;
long long d = 100200300402LL;
long long e = 100200300403LL;
long long f = 100200300404LL;
long long g = 100200300405LL;
long long h = 100200300406LL;
long long i = 541934347449LL;
long long j = 727503252688LL;
int compact(long long x) {
/* probably _csa_ */
switch (x) {
case 100200300401LL: return 23;
case 100200300402LL: return 29;
case 100200300403LL: return 31;
case 100200300405LL: return 37;
case 100200300406LL: return 41;
default: return 43;
}
}
int sparse(long long x) {
/* probably _csb_ */
switch (x) {
case -719560752603LL: return 47;
case -319239774717LL: return 53;
case 100200300403LL: return 59;
case 541934347449LL: return 61;
case 727503252688LL: return 67;
default: return 71;
}
}
void _m_a_i_n(void) {
ASSERT(compact(a) == 43);
ASSERT(compact(b) == 43);
ASSERT(compact(c) == 23);
ASSERT(compact(d) == 29);
ASSERT(compact(e) == 31);
ASSERT(compact(f) == 43);
ASSERT(compact(g) == 37);
ASSERT(compact(h) == 41);
ASSERT(compact(i) == 43);
ASSERT(compact(j) == 43);
ASSERT(sparse(a) == 47);
ASSERT(sparse(b) == 53);
ASSERT(sparse(c) == 71);
ASSERT(sparse(d) == 71);
ASSERT(sparse(e) == 59);
ASSERT(sparse(f) == 71);
ASSERT(sparse(g) == 71);
ASSERT(sparse(h) == 71);
ASSERT(sparse(i) == 61);
ASSERT(sparse(j) == 67);
finished();
}