diff --git a/mach/sparc/ce_cg/.distr b/mach/sparc/ce_cg/.distr new file mode 100644 index 000000000..c9c9751db --- /dev/null +++ b/mach/sparc/ce_cg/.distr @@ -0,0 +1,2 @@ +convert.c +proto.make diff --git a/mach/sparc/ce_cg/convert.c b/mach/sparc/ce_cg/convert.c new file mode 100644 index 000000000..1db46e34f --- /dev/null +++ b/mach/sparc/ce_cg/convert.c @@ -0,0 +1,111 @@ +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + */ +#ifndef NORCSID +static char rcsid[] = "$Header$"; +#endif + +/* This program converts either human-readable or compact EM + assembly code to calls of the procedure-interface. + It must be linked with two libraries: + - a library to read EM code, according to read_em(3) + - a library implementing the em_code(3) interface. + Thus, this program could serve as an EM_encoder, an + EM_decoder, or some code generator, depending on how it is + linked. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +char *filename; /* Name of input file */ +char *out_file; /* Name of output file */ +int errors; /* Number of errors */ +int debug; +extern char *C_error; + +main(argc,argv) + char **argv; +{ + struct e_instr buf; + register struct e_instr *p = &buf; + int ac; + char **av; + + filename= 0; + out_file= 0; + debug= 0; + for (ac=argc-1,av=argv+1;ac;ac--,av++) + { + if (av[0][0]=='-' && av[0][1]=='d' && av[0][2]==0) + { + debug= 1; + continue; + } + if (!filename) + { + if (strcmp(*av, "-")) + filename= *av; + } + else if (!out_file) + { + if (strcmp(*av, "-")) + out_file= *av; + } + else + fatal ("too many arguments"); + } + if (!EM_open(filename)) { + fatal(EM_error); + } + EM_getinstr(p); + C_init((arith) EM_wordsize, (arith) EM_pointersize); + if (!C_open(out_file)) { + fatal("C_open failed"); + } + C_magic(); + while (p->em_type != EM_EOF) { + if (p->em_type == EM_FATAL) { + fatal("%s", EM_error); + } + if (EM_error) { + error("%s", EM_error); + } + if (p->em_type != EM_ERROR && !C_out(p)) { + error("%s", C_error); + } + EM_getinstr(p); + } + C_close(); + EM_close(); + exit(errors); +} + +/* VARARGS */ +error(s,a1,a2,a3,a4) + char *s; +{ + fprint(STDERR, + "%s, line %d: ", + filename ? filename : "standard input", + EM_lineno); + fprint(STDERR,s,a1,a2,a3,a4); + fprint(STDERR, "\n"); + errors++; +} + +/* VARARGS */ +fatal(s,a1,a2,a3,a4) + char *s; +{ + if (C_busy()) C_close(); + error(s,a1,a2,a3,a4); + exit(1); +} diff --git a/mach/sparc/ce_cg/proto.make b/mach/sparc/ce_cg/proto.make new file mode 100644 index 000000000..c3e96d7e2 --- /dev/null +++ b/mach/sparc/ce_cg/proto.make @@ -0,0 +1,42 @@ +# $Header$ + +#PARAMS do not remove this line! + +SRC_DIR=$(SRC_HOME)/mach/sparc/ce_cg +MACH=sparc +LIB_DIR=$(TARGET_HOME)/modules/lib +EM_LIB=$(TARGET_HOME)/lib.bin +INCLUDE=-I$(TARGET_HOME)/modules/h -I$(TARGET_HOME)/h +CE_A= $(TARGET_HOME)/lib.bin/$(MACH)/ce.$(LIBSUF) +BACK_A= $(TARGET_HOME)/lib.bin/$(MACH)/back.$(LIBSUF) + +CFLAGS=$(INCLUDE) -DCODE_EXPANDER $(COPTIONS) +LDFLAGS=$(LDOPTIONS) +LDLIBS=$(LIB_DIR)/libread_emk.$(LIBSUF) $(CE_A) $(BACK_A) \ + $(LIB_DIR)/libprint.$(LIBSUF) $(LIB_DIR)/libstring.$(LIBSUF) \ + $(LIB_DIR)/liballoc.$(LIBSUF) $(LIB_DIR)/libsystem.$(LIBSUF) \ + $(EM_LIB)/em_data.$(LIBSUF) $(LIB_DIR)/libflt.$(LIBSUF) + +all: cg + +install: all + -mkdir $(TARGET_HOME)/lib.bin/$(MACH) + cp cg $(TARGET_HOME)/lib.bin/$(MACH)/cg + +cmp: all + cmp cp cg $(TARGET_HOME)/lib.bin/$(MACH)/cg + +clean: + rm -f *.$(SUF) cg + +cg: convert.$(SUF) $(CE_A) $(BACK_A) + $(CC) $(LDFLAGS) -o cg convert.$(SUF) $(LDLIBS) + +convert.$(SUF): $(SRC_DIR)/convert.c + $(CC) $(CFLAGS) -c $(SRC_DIR)/convert.c + +pr: + @pr $(SRC_DIR)/proto.make $(SRC_DIR)/convert.c + +opr: + make pr | opr diff --git a/mach/sparc/libem/.distr b/mach/sparc/libem/.distr new file mode 100644 index 000000000..d2b4f2884 --- /dev/null +++ b/mach/sparc/libem/.distr @@ -0,0 +1,2 @@ +LIST +libem_s.a diff --git a/mach/sparc/libem/LIST b/mach/sparc/libem/LIST new file mode 100644 index 000000000..114e753a3 --- /dev/null +++ b/mach/sparc/libem/LIST @@ -0,0 +1,9 @@ +libem_s.a +csa.s +csb.s +dvu.s +lar.s +muldiv.s +nop.s +shp.s +trp.s diff --git a/mach/sparc/libem/csa.s b/mach/sparc/libem/csa.s new file mode 100644 index 000000000..da12aba03 --- /dev/null +++ b/mach/sparc/libem/csa.s @@ -0,0 +1,37 @@ +.global csa + +ECASE=20 +STACK_CLICK=4 + +csa: + ! jump table address in %o0 + ! index in %o1 + + ld [%o0], %o4 ! default address + ld [%o0+4], %o2 + subcc %o1, %o2, %o1 ! index - lower bound + bl 1f + ld [%o0+2*4], %o3 + cmp %o1, %o3 ! rel. index, upper - lower bound + bgt 1f + nop + sll %o1, 2, %o5 + add %o0, %o5, %o3 ! %o3 = @jump address + ld [%o3+12], %o2 ! %o2 = jump address + tst %o2 + be 1f + nop + jmp %o2 + nop +1: + tst %o4 + beq 2f + nop + jmp %o4 + nop +2: + mov ECASE, %o0 + set trp, %g1 + jmp %g1 + nop +.align 4 diff --git a/mach/sparc/libem/csb.s b/mach/sparc/libem/csb.s new file mode 100644 index 000000000..c9d6b6b9f --- /dev/null +++ b/mach/sparc/libem/csb.s @@ -0,0 +1,40 @@ +.global csb +ECASE=20 + +csb: + ! case descriptor in %o0 + ! index in %o1 + ld [%o0], %o2 ! default jump address + ld [%o0+4], %o3 ! # entries + inc 8, %o0 + tst %o3 + be 3f + nop + dec %o3 + set 0xffff, %o4 + and %o3, %o4, %o5 + sll %o5, 3, %o3 +1: + ld [%o0+%o3], %o4 + cmp %o4, %o1 + be 2f + nop + deccc 8, %o3 + bge 1b + nop + b 3f + nop +2: + inc 4, %o3 + ld [%o0+%o3], %o2 +3: + tst %o2 + be 4f + nop + jmp %o2 + nop +4: + set ECASE, %o0 + set trp, %g1 + jmp %g1 + nop diff --git a/mach/sparc/libem/dvu.s b/mach/sparc/libem/dvu.s new file mode 100644 index 000000000..7e77c1059 --- /dev/null +++ b/mach/sparc/libem/dvu.s @@ -0,0 +1,101 @@ +.global dvu4 +.global dvi4 + +dvu4: +! %o0' = %o0 / %o1 +! %o1' = %o0 % %o1 + tst %o1 + be 0f + nop + clr %o5 + tst %o0 + bge 3f /* jump if msb clear */ + nop + + clr %o2 + mov %o1, %o3 + clr %o4 +1: tst %o1 + bl 5f /* jump if msb set */ + nop + sll %o1, 1, %o1 + inc %o4 + b 1b + nop + + +dvi4: +! %o2 = %o0 / %o1 +! %o3 = %o0 % %o1 + tst %o1 + be 0f + clr %o5 + tst %o0 + bge 1f + nop + neg %o0 + xor %o5, 1, %o5 +1: + tst %o1 + bge 3f + nop + neg %o1 + xor %o5, 3, %o5 + +3: /* div common */ + clr %o2 + mov %o1, %o3 + clr %o4 + +4: + cmp %o1, %o0 + bgu 5f + nop + inc %o4 + sll %o1, 1, %o1 + b 4b + nop + +5: /* div common for dvu4 && ( %o0 & 0x80000000) */ + sll %o2, 1, %o2 + subcc %o0, %o1, %o0 + bgeu 3f + nop + add %o0, %o1, %o0 + b 4f + nop +3: + inc %o2 +4: + srl %o1, 1, %o1 + tst %o4 + bz 5f + nop + dec %o4 + b 5b + nop + +5: + andcc %o5, 1, %g0 + bz 6f + nop + tst %o0 + bz 7f + nop + inc %o2 + sub %o3, %o0, %o0 +7: + neg %o2 +6: + andcc %o5, 2, %g0 + bz 8f + nop + neg %o0 +8: + mov %o0, %o1 + mov %o2, %o0 + retl + nop + +0: /* divide by zero */ + ta 2 diff --git a/mach/sparc/libem/lar.s b/mach/sparc/libem/lar.s new file mode 100644 index 000000000..b6f3a48a8 --- /dev/null +++ b/mach/sparc/libem/lar.s @@ -0,0 +1,104 @@ +.global aar +.global lar +.global sar + +aar: ! %o0 = descr %o1 = index %o2 = array_ptr + + save %sp, -64, %sp + ld [%i0], %o0 ! lower bound + subcc %i1, %o0, %o1 ! 0..N-1 + bl 1f ! <0 + nop + ld [%i0+4], %o0 ! n + cmp %o1, %o0 + bgt 1f ! > N + nop + call mli4 ! descr *= n.size + ld [%i0+8], %o0 ! el.size + add %i2, %o0, %i0 ! &base_addr[n] + ret + restore ! delay slot +1: restore + set EARRAY, %o0 + call trp + nop + retl + nop + +lar: ! %o0 = descr %o1 = index %o2 = array_ptr + + mov %o7, %o4 + call aar + mov %o0, %o3 + mov %o4, %o7 + + ! %o0 = address of el, %o1 = sizeof(el), %o2 = word, %o3 = descr + ld [%o3+8], %o1 ! el.size + cmp %o1, 1 + bne 2f + nop + ldub [%o0], %o2 ! el.size == 1 + dec 4, %l0 + retl + st %o2, [%l0] ! delay slot +2: cmp %o1,2 + bne 3f + nop + lduh [%o0], %o2 ! el.size == 2 + dec 4, %l0 + retl + st %o2, [%l0] ! delay slot +3: cmp %o1, 4 + bne 4f + nop + ld [%o0], %o2 + dec 4, %l0 + retl + st %o2, [%l0] ! delay slot +4: sub %l0, %o1, %l0 +5: deccc 4, %o1 + ld [%o0+%o1], %o2 + bnz 5b + st %o2, [%l0+%o1] + retl + nop + +sar: ! %o0 = descr %o1 = index %o2 = array_ptr + + mov %o7, %o4 + call aar + mov %o0, %o3 + mov %o4, %o7 + + ! %o0 = address of el, %o1 = sizeof(el), %o2 = word, %o3 = descr + + ld [%o3+8], %o1 ! el.size + cmp %o1, 1 + bne 2f + nop + ld [%l0], %o2 + stb %o2, [%o0] + retl + inc 4, %l0 ! delay slot +2: cmp %o1,2 + bne 3f + nop + ld [%l0], %o2 + sth %o2, [%o0] + retl + inc 4, %l0 ! delay slot +3: cmp %o1, 4 + bne 4f + nop + ld [%l0], %o2 + st %o2, [%o0] + retl + inc 4, %l0 ! delay slot + +4: mov %o1, %o4 +5: deccc 4, %o1 + ld [%l0+%o1], %o2 + bnz 5b + st %o2, [%o0+%o1] ! delay slot + retl + add %l0, %o4, %l0 ! delay slot diff --git a/mach/sparc/libem/muldiv.s b/mach/sparc/libem/muldiv.s new file mode 100644 index 000000000..305469dfa --- /dev/null +++ b/mach/sparc/libem/muldiv.s @@ -0,0 +1,148 @@ +.global mli4 +.global mlu4 + +mli4: + mov %o0, %y + andncc %o0, 0xfff, %g0 + bn mul_shortway1 + nop + andcc %g0, %g0, %o4 + + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %g0, %o4 + + tst %o0 + rd %y, %o0 + bge 1f + tst %o0 + sub %o4, %o1, %o4 +1: retl + mov %o4, %o1 + +mul_shortway1: + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %g0, %o4 + + rd %y, %o5 + sll %o4, 12, %o0 + srl %o5, 20, %o5 + + or %o5, %o4, %o0 + retl + mov %o4, %o1 + +mlu4: + or %o0, %o1, %o4 + mov %o0, %y + andncc %o4, 0xfff, %o5 + bn mul_shortway2 + andcc %g0, %g0, %o4 + + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %g0, %o4 + + tst %o0 + bge 1f + nop + add %o4, %o0, %o4 +1: + rd %y, %o0 + retl + addcc %o4, %g0, %o1 + +mul_shortway2: + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %o1, %o4 + mulscc %o4, %g0, %o4 + + rd %y, %o5 + sll %o4, 12, %o0 + srl %o5, 20, %o5 + + or %o5, %o4, %o0 + retl + addcc %g0, %g0, %o1 + diff --git a/mach/sparc/libem/nop.s b/mach/sparc/libem/nop.s new file mode 100644 index 000000000..bb525dbed --- /dev/null +++ b/mach/sparc/libem/nop.s @@ -0,0 +1,5 @@ +.global nop + +nop: + retl + nop diff --git a/mach/sparc/libem/shp.s b/mach/sparc/libem/shp.s new file mode 100644 index 000000000..9e5950554 --- /dev/null +++ b/mach/sparc/libem/shp.s @@ -0,0 +1,30 @@ +.global strhp +EHEAP=17 + +strhp: ! %o0 = new heap pointer + save %sp, -64, %sp + set reghp, %o1 + st %i0, [%o1] ! it'll probably go right, anyway + set limhp, %o1 + ld [%o1], %o2 + cmp %i0, limhp + blt 1f + nop + add %i0, 0x400, %i0 ! extra 1K + andn %i0, 0x3ff, %o0 + st %o0, [%o1] ! prematurely set limhp + call brk + nop + tst %o0 + blt 2f ! failed + nop + set limhp, %o1 + st %o0, [%o1] +1: ret + restore +2: + restore + set EHEAP, %o0 + set trp, %o1 + jmp %o1 + nop diff --git a/mach/sparc/libem/trp.s b/mach/sparc/libem/trp.s new file mode 100644 index 000000000..87fb48cd7 --- /dev/null +++ b/mach/sparc/libem/trp.s @@ -0,0 +1,35 @@ +.global trp, write + +trp: + set trpim, %o1 + ld [%o1], %o2 + srl %o2, %o0, %o1 + andcc %o2, 1, %g0 + bz 2f + nop + retl + nop +2: + set trppc, %o1 + ld [%o1], %o1 + tst %o1 + bz 1f + nop + dec 4, %l0 + st %o0, [%l0] + jmp %o1 + nop +1: + save %sp, -64, %sp + set 2, %o0 + set message, %o1 + set message_high-message, %o2 + call write + nop + restore + ta 2 + st %g0, [%g0] + +message: + .ascii "the error code is in %o0\n" +message_high: