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:
parent
d6413c1a11
commit
0b0c3d5b60
|
@ -1,7 +1,7 @@
|
||||||
for _, plat in ipairs(vars.plats) do
|
for _, plat in ipairs(vars.plats) do
|
||||||
acklibrary {
|
acklibrary {
|
||||||
name = "lib_"..plat,
|
name = "lib_"..plat,
|
||||||
srcs = { "./*.s" }, -- divrem8.s
|
srcs = { "./*.s" }, -- csb8.s
|
||||||
vars = { plat = plat },
|
vars = { plat = plat },
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
35
mach/i386/libem/csa8.s
Normal file
35
mach/i386/libem/csa8.s
Normal 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
39
mach/i386/libem/csb8.s
Normal 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
|
|
@ -3074,6 +3074,11 @@ with BXREG ACC
|
||||||
kills ALL
|
kills ALL
|
||||||
gen jmp {label, ".csa4"}
|
gen jmp {label, ".csa4"}
|
||||||
|
|
||||||
|
pat csa $1==8
|
||||||
|
with BXREG ACC DXREG
|
||||||
|
kills ALL
|
||||||
|
gen jmp {label, ".csa8"}
|
||||||
|
|
||||||
pat csa !defined($1)
|
pat csa !defined($1)
|
||||||
with rm-BXREG-ACC BXREG ACC
|
with rm-BXREG-ACC BXREG ACC
|
||||||
kills ALL
|
kills ALL
|
||||||
|
@ -3086,6 +3091,11 @@ with BXREG ACC
|
||||||
kills ALL
|
kills ALL
|
||||||
gen jmp {label, ".csb4"}
|
gen jmp {label, ".csb4"}
|
||||||
|
|
||||||
|
pat csb $1==8
|
||||||
|
with BXREG ACC DXREG
|
||||||
|
kills ALL
|
||||||
|
gen jmp {label, ".csb8"}
|
||||||
|
|
||||||
pat csb !defined($1)
|
pat csb !defined($1)
|
||||||
with rm-BXREG-ACC BXREG ACC
|
with rm-BXREG-ACC BXREG ACC
|
||||||
gen cmp %1,{ANYCON,4}
|
gen cmp %1,{ANYCON,4}
|
||||||
|
|
|
@ -2,7 +2,7 @@ for _, plat in ipairs(vars.plats) do
|
||||||
acklibrary {
|
acklibrary {
|
||||||
name = "lib_"..plat,
|
name = "lib_"..plat,
|
||||||
srcs = {
|
srcs = {
|
||||||
"./*.s", -- added divrem8.s
|
"./*.s", -- csb8.s
|
||||||
"./*.c"
|
"./*.c"
|
||||||
},
|
},
|
||||||
vars = { plat = plat },
|
vars = { plat = plat },
|
||||||
|
|
39
mach/m68020/libem/csa8.s
Normal file
39
mach/m68020/libem/csa8.s
Normal 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
39
mach/m68020/libem/csb8.s
Normal 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
|
|
@ -6057,6 +6057,11 @@ with any4 D_REG4+DLOCAL+const4+absolute4 STACK
|
||||||
move %2,dl0
|
move %2,dl0
|
||||||
jmp {absolute4, ".csa4"}
|
jmp {absolute4, ".csa4"}
|
||||||
|
|
||||||
|
pat csa $1==8
|
||||||
|
with any4 STACK
|
||||||
|
gen move %1,a0
|
||||||
|
jmp {absolute4, ".csa8"}
|
||||||
|
|
||||||
#if WORD_SIZE==2
|
#if WORD_SIZE==2
|
||||||
pat csb $1==2
|
pat csb $1==2
|
||||||
#if TBL68020
|
#if TBL68020
|
||||||
|
@ -6079,6 +6084,11 @@ with any4 D_REG4+DLOCAL+const4+absolute4 STACK
|
||||||
move %2,dl0
|
move %2,dl0
|
||||||
jmp {absolute4, ".csb4"}
|
jmp {absolute4, ".csb4"}
|
||||||
|
|
||||||
|
pat csb $1==8
|
||||||
|
with any4 STACK
|
||||||
|
gen move %1,a0
|
||||||
|
jmp {absolute4, ".csb8"}
|
||||||
|
|
||||||
pat dch leaving loi 4
|
pat dch leaving loi 4
|
||||||
|
|
||||||
#if WORD_SIZE==2
|
#if WORD_SIZE==2
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
|
||||||
include("plat/build.lua")
|
include("plat/build.lua")
|
||||||
|
|
||||||
definerule("plat_testsuite",
|
definerule("plat_testsuite",
|
||||||
{
|
{
|
||||||
plat = { type="string" },
|
plat = { type="string" },
|
||||||
method = { 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"}},
|
sets = { type="table", default={"core", "b", "bugs", "m2", "floats", "long-long"}},
|
||||||
skipsets = { type="table", default={}},
|
skipsets = { type="table", default={}},
|
||||||
tests = { type="targets", default={} },
|
tests = { type="targets", default={} },
|
||||||
|
|
62
tests/plat/long-long/llswitch_e.c
Normal file
62
tests/plat/long-long/llswitch_e.c
Normal 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();
|
||||||
|
}
|
Loading…
Reference in a new issue