Convert library asm files to GAS syntax

This commit is contained in:
Arun Thomas 2010-03-03 14:27:30 +00:00
parent bf7397b64e
commit cbd276e4ce
302 changed files with 2544 additions and 2451 deletions

View file

@ -97,7 +97,7 @@ typedef enum opcode { /* 80486 opcodes, from the i486 reference manual.
FSIN,
FSINCOS,
FSQRT,
FSTD, FSTS, FSTPX, FSTPD, FSTPS,
FSTD, FSTS, FSTP, FSTPX, FSTPD, FSTPS,
FSTCW,
FSTENV,
FSTSW,

View file

@ -14,11 +14,15 @@ char *copystr(const char *s);
int isanumber(const char *s);
extern int asm_mode32; /* In 32 bit mode if true. */
extern int prepend_underscores; /* Prepend underscores to symbols */
#define use16() (!asm_mode32)
#define use32() ((int) asm_mode32)
#define set_use16() ((void) (asm_mode32= 0))
#define set_use32() ((void) (asm_mode32= 1))
#define underscore_mode() (prepend_underscores)
#define enable_underscore_mode() ((void)(prepend_underscores= 1))
extern int err_code; /* Exit code. */
#define set_error() ((void) (err_code= EXIT_FAILURE))

View file

@ -160,6 +160,7 @@ static mnemonic_t mnemtab[] = {
{ FSTCW, "fstcw" },
{ FSTD, "fstd" },
{ FSTENV, "fstenv" },
{ FSTP, "fstp" },
{ FSTPD, "fstpd" },
{ FSTPS, "fstps" },
{ FSTPX, "fstpx" },
@ -311,6 +312,8 @@ static mnemonic_t mnemtab[] = {
};
#define farjmp(o) ((o) == JMPF || (o) == CALLF)
#define data_op(o) ((o) == DOT_DATA1 || (o) == DOT_DATA2 || (o) == DOT_DATA4)
#define define_op(o) ((o) == DOT_DEFINE)
static FILE *ef;
static long eline= 1;
@ -393,11 +396,15 @@ static void ack_put_expression(asm86_t *a, expression_t *e, int deref)
assert(e != nil);
isglob = syms_is_global(e->name);
if (underscore_mode())
isglob = syms_is_global(e->name);
else
isglob = 0;
switch (e->operator) {
case ',':
if (dialect == NCC && farjmp(a->opcode)) {
if (data_op(a->opcode) || define_op(a->opcode)
|| (dialect == NCC && farjmp(a->opcode))) {
/* ACK jmpf seg:off -> NCC jmpf off,seg */
ack_put_expression(a, e->right, deref);
ack_printf(", ");
@ -546,7 +553,7 @@ void ack_emit_instruction(asm86_t *a)
} else
if (a->opcode == DOT_LABEL) {
assert(a->args->operator == ':');
if (syms_is_global(a->args->name))
if (underscore_mode() && syms_is_global(a->args->name))
ack_printf("_%s:", a->args->name);
else
ack_printf("%s:", a->args->name);
@ -599,7 +606,7 @@ void ack_emit_instruction(asm86_t *a)
&& a->args->operator == ','
&& a->args->left->operator == 'W'
) {
if (syms_is_global(a->args->left->name))
if (underscore_mode() && syms_is_global(a->args->left->name))
ack_printf(".define\t_%s; ", a->args->left->name);
else
ack_printf(".define\t%s; ", a->args->left->name);
@ -668,7 +675,9 @@ void ack_emit_instruction(asm86_t *a)
/* we are translating from GNU */
if (a->args && a->args->operator == ','
/* don't swap ljmp prefixed with segment */
&& a->opcode != JMPF) {
&& a->opcode != JMPF
&& !data_op(a->opcode)
&& !define_op(a->opcode)) {
expression_t * tmp;
tmp = a->args->right;

View file

@ -10,6 +10,7 @@ static char version[] = "1.11";
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <getopt.h>
#include "asmconv.h"
#include "asm86.h"
#include "languages.h"
@ -55,6 +56,8 @@ int isanumber(const char *s)
/* "Invisible" globals. */
int asm_mode32= (sizeof(int) == 4);
int err_code= EXIT_SUCCESS;
/* Prepend underscores to symbols */
int prepend_underscores = 0;
int main(int argc, char **argv)
{
@ -65,28 +68,40 @@ int main(int argc, char **argv)
char *lang_parse, *lang_emit, *input_file, *output_file;
asm86_t *instr;
char banner[80];
char c;
opterr = 0;
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'm') {
if (strcmp(argv[1], "-mi86") == 0) {
set_use16();
} else
if (strcmp(argv[1], "-mi386") == 0) {
set_use32();
} else {
fprintf(stderr, "asmconv: '%s': unknown machine\n",
argv[1]+2);
}
argc--;
argv++;
}
while ((c = getopt (argc, argv, "m:u")) != -1)
switch (c)
{
case 'm':
if (strcmp(optarg, "i86") == 0) {
set_use16();
} else
if (strcmp(optarg, "i386") == 0) {
set_use32();
}
else {
fprintf(stderr, "asmconv: '%s': unknown machine\n",
optarg);
exit(EXIT_FAILURE);
}
break;
case 'u':
enable_underscore_mode();
break;
default:
fprintf(stderr, "Usage: gas2ack [input-file [output-file]]\n");
exit(EXIT_FAILURE);
}
if (argc > 3) {
if ((argc - optind < 1) || (argc - optind > 2)) {
fprintf(stderr, "Usage: gas2ack [input-file [output-file]]\n");
exit(EXIT_FAILURE);
}
input_file= argc < 1 ? nil : argv[1];
output_file= argc < 2 ? nil : argv[2];
input_file= (argc - optind) < 1 ? nil : argv[optind];
output_file= (argc - optind) < 2 ? nil : argv[optind+1];
parse_init= gnu_parse_init;
get_instruction= gnu_get_instruction;

View file

@ -20,7 +20,12 @@ typedef struct mnemonic { /* GNU as86 mnemonics translation table. */
optype_t optype;
} mnemonic_t;
static mnemonic_t mnemtab[] = { /* This array is sorted. */
/***************************************************************
* *
* NOTE: You MUST keep this array sorted by the first column. *
* *
**************************************************************/
static mnemonic_t mnemtab[] = {
{ ".ascii", DOT_ASCII, PSEUDO },
{ ".asciz", DOT_ASCIZ, PSEUDO },
{ ".assert", DOT_ASSERT, PSEUDO },
@ -30,9 +35,6 @@ static mnemonic_t mnemtab[] = { /* This array is sorted. */
{ ".byte", DOT_DATA1, PSEUDO },
{ ".comm", DOT_COMM, PSEUDO },
{ ".data", DOT_DATA, PSEUDO },
{ ".data1", DOT_DATA1, PSEUDO },
{ ".data2", DOT_DATA2, PSEUDO },
{ ".data4", DOT_DATA4, PSEUDO },
{ ".end", DOT_END, PSEUDO },
{ ".extern", DOT_EXTERN, PSEUDO },
{ ".file", DOT_FILE, PSEUDO },
@ -85,10 +87,9 @@ static mnemonic_t mnemtab[] = { /* This array is sorted. */
{ "cmc", CMC, WORD },
{ "cmpb", CMP, BYTE },
{ "cmpl", CMP, WORD },
{ "cmps", CMPS, WORD },
{ "cmpsb", CMPS, BYTE },
{ "cmpsl", CMPS, OWORD },
{ "cmpsw", CMPS, WORD },
{ "cmpsl", CMPS, WORD },
{ "cmpsw", CMPS, OWORD },
{ "cmpw", CMP, OWORD },
{ "cmpxchg", CMPXCHG, WORD },
{ "cpuid", CPUID, WORD },
@ -152,8 +153,8 @@ static mnemonic_t mnemtab[] = { /* This array is sorted. */
{ "fisubs", FISUBS, WORD },
{ "fld1", FLD1, WORD },
{ "fldcw", FLDCW, WORD },
{ "fldd", FLDD, WORD },
{ "fldenv", FLDENV, WORD },
{ "fldl", FLDD, WORD },
{ "fldl2e", FLDL2E, WORD },
{ "fldl2t", FLDL2T, WORD },
{ "fldlg2", FLDLG2, WORD },
@ -170,8 +171,8 @@ static mnemonic_t mnemtab[] = { /* This array is sorted. */
{ "fnop", FNOP, WORD },
{ "fnsave", FNSAVE, WORD },
{ "fnstcw", FNSTCW, WORD },
{ "fnstsw", FNSTSW, WORD },
{ "fnstenv", FSTENV, WORD },
{ "fnstsw", FNSTSW, WORD },
{ "fpatan", FPATAN, WORD },
{ "fprem", FPREM, WORD },
{ "fprem1", FPREM1, WORD },
@ -183,12 +184,13 @@ static mnemonic_t mnemtab[] = { /* This array is sorted. */
{ "fsin", FSIN, WORD },
{ "fsincos", FSINCOS, WORD },
{ "fsqrt", FSQRT, WORD },
{ "fstcw", FSTCW, WORD },
{ "fstd", FSTD, WORD },
{ "fstpd", FSTPD, WORD },
{ "fstp", FSTP, WORD },
{ "fstpl", FSTPD, WORD },
{ "fstps", FSTPS, WORD },
{ "fstpx", FSTPX, WORD },
{ "fsts", FSTS, WORD },
{ "fstcw", FSTCW, WORD },
{ "fstsw", FSTSW, WORD },
{ "fsubd", FSUBD, WORD },
{ "fsubp", FSUBP, WORD },
@ -697,6 +699,7 @@ static expression_t *gnu_get_oplist(asm86_t * a, int *pn, int deref)
token_t *t;
int sreg;
if ((e= gnu_get_operand(a, pn, deref)) == nil) return nil;
t = get_token(*pn);
@ -862,13 +865,16 @@ static asm86_t *gnu_get_statement(void)
break;
case DOT_DEFINE:
case DOT_EXTERN:
syms_add_global_csl(a->args);
if (underscore_mode())
syms_add_global_csl(a->args);
break;
case DOT_COMM:
syms_add_global(a->args->left->name);
if (underscore_mode())
syms_add_global(a->args->left->name);
break;
case DOT_LCOMM:
syms_add(a->args->left->name);
if(underscore_mode())
syms_add(a->args->left->name);
break;
case JMPF:
case CALLF:
@ -940,7 +946,8 @@ asm86_t *gnu_get_instruction(void)
a->args= e= new_expr();
e->operator= ':';
e->name= copystr(t->name);
syms_add(t->name);
if (underscore_mode())
syms_add(t->name);
skip_token(2);
} else
if (t->type == T_WORD && get_token(1)->symbol == '=') {
@ -971,7 +978,8 @@ asm86_t *gnu_get_instruction(void)
a->args= new_expr();
a->args->operator= '=';
a->args->name= copystr(t->name);
syms_add(t->name);
if (underscore_mode())
syms_add(t->name);
a->args->middle= e;
skip_token(n+1);
}

View file

@ -1,3 +1,5 @@
20100303:
Gas2ack updates: Run 'make install' in commands/i386/gas2ack
20100215:
Make(1) has been replaced: Run 'make install' in commands/make
Mkdep updates: Copy commands/scripts/mkdep.sh to /usr/bin/mkdep

View file

@ -1,4 +1,4 @@
.SUFFIXES: .o .e
.SUFFIXES: .o .e .S
# Treated like a C file
.e.o:
@ -8,3 +8,15 @@
# ${OBJCOPY} -x ${.TARGET}
# .endif
ASMCONV=gas2ack
AFLAGS+=-D__ASSEMBLY__ -D_EM_WSIZE=4 -D__minix -I/usr/src/include -w -wo
CPP.s=${CC} -E ${AFLAGS}
ASMCONVFLAGS+=-mi386
# Need to convert ACK assembly files to GNU assembly before building
.S.o:
${_MKTARGET_COMPILE}
${CPP.s} ${COPTS.${.IMPSRC:T}} ${CPUFLAGS.${.IMPSRC:T}} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC} -o ${.PREFIX}.gnu.s
${ASMCONV} ${ASMCONVFLAGS} ${.PREFIX}.gnu.s ${.PREFIX}.ack.s
${COMPILE.s} ${COPTS.${.IMPSRC:T}} ${CPUFLAGS.${.IMPSRC:T}} ${CPPFLAGS.${.IMPSRC:T}} ${.PREFIX}.ack.s -o ${.TARGET}
rm -rf ${.PREFIX}.ack.s ${.PREFIX}.gnu.s

View file

@ -1,9 +1,8 @@
.SUFFIXES: .o .s .gs
.SUFFIXES: .o .s
ASMCONV=asmconv
CPP.s=${CC} ${AFLAGS} -E -x assembler-with-cpp
ASMCONVFLAGS+=-mi386 ack gnu
ASSEMBLE=gas ${AFLAGS}
# Need to convert ACK assembly files to GNU assembly before building
.s.o:
@ -12,8 +11,3 @@ ASSEMBLE=gas ${AFLAGS}
${ASMCONV} ${ASMCONVFLAGS} ${.PREFIX}.ack.s ${.PREFIX}.gnu.s
${COMPILE.s} ${COPTS.${.IMPSRC:T}} ${CPUFLAGS.${.IMPSRC:T}} ${CPPFLAGS.${.IMPSRC:T}} ${.PREFIX}.gnu.s -o ${.TARGET}
rm -rf ${.PREFIX}.ack.s ${.PREFIX}.gnu.s
# GNU Assembly file
.gs.o:
${_MKTARGET_COMPILE}
${ASSEMBLE} ${COPTS.${.IMPSRC:T}} ${CPUFLAGS.${.IMPSRC:T}} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC} -o ${.TARGET}

View file

@ -43,17 +43,17 @@ clean:
# How to build it
klib386.o: klib386.S
$(CC) $(CFLAGS) -E -D__ASSEMBLY__ -o $@.tmp $<
gas2ack $@.tmp $@.s
gas2ack -u $@.tmp $@.s
$(CC) $(CFLAGS) -c -o $@ $@.s
mpx386.o: mpx386.S
$(CC) $(CFLAGS) -E -D__ASSEMBLY__ -o $@.tmp $<
gas2ack $@.tmp $@.s
gas2ack -u $@.tmp $@.s
$(CC) $(CFLAGS) -c -o $@ $@.s
apic_asm.o: apic_asm.S
$(CC) $(CFLAGS) -E -D__ASSEMBLY__ -o $@.tmp $<
gas2ack $@.tmp $@.s
gas2ack -u $@.tmp $@.s
$(CC) $(CFLAGS) -c -o $@ $@.s
$(HEAD): mpx386.o

View file

@ -20,6 +20,7 @@
.globl apic_hwint14
.globl apic_hwint15
.text
#define APIC_IRQ_HANDLER(irq) \
push $irq ;\
call irq_handle /* intr_handle(irq_handlers[irq]) */ ;\

View file

@ -1,6 +1,5 @@
/* sections */
.text; .data; .data; .bss
#include <minix/config.h>
#include <minix/const.h>

View file

@ -4,7 +4,7 @@
AFLAGS+= -O -D_MINIX -D_POSIX_SOURCE
SRCS= crtso.s
SRCS= crtso.S
OBJS= crtso.o
realall: ${OBJS}

121
lib/csu/i386/crtso.S Normal file
View file

@ -0,0 +1,121 @@
/* This is the C run-time start-off routine. It's job is to take the */
/* arguments as put on the stack by EXEC, and to parse them and set them up the */
/* way _main expects them. */
/* It also initializes environ when this variable isn't defined by the */
/* programmer. The detection of whether environ belong to us is rather */
/* simplistic. We simply check for some magic value, but there is no other */
/* way. */
#include <sys/vm_i386.h>
.globl begtext, begdata, begbss
.text
begtext:
#ifdef __ACK__
.rom
#else
.data
#endif
begrom:
.data
begdata:
.bss
begbss:
.globl crtso, __penviron, __penvp, __fpu_present
.globl __minix_datastart, __minix_mainjump, __minix_unmapzero
.extern _main, _exit
#if defined(__ELF__)
.section .init
#else
.text
#endif
#if defined(__ELF__)
.globl __start
__start:
#endif
crtso:
xorl %ebp, %ebp /* clear for backtrace of core files */
movl (%esp), %eax /* argc */
leal 4(%esp), %edx /* argv */
leal 8(%esp,%eax,4), %ecx /* envp */
/* Test if environ is in the initialized data area and is set to our */
/* magic number. If so then it is not redefined by the user. */
movl $_environ, %ebx
cmpl $__edata, %ebx /* within initialized data? */
jae 0f
testb $3, %bl /* aligned? */
jne 0f
cmpl $0x53535353, (%ebx) /* is it our environ? */
jne 0f
movl %ebx, __penviron /* _penviron = &environ; */
0:
movl __penviron, %ebx
movl %ecx, (%ebx) /* *_penviron = envp; */
push %ecx /* push envp */
push %edx /* push argv */
push %eax /* push argc */
/* Test the EM bit of the MSW to determine if an FPU is present and */
/* set __fpu_present if one is found. */
smsw %ax
testb $0x4, %al /* EM bit in MSW */
sete __fpu_present /* True if not set */
jmp __minix_mainjump
.balign I386_PAGE_SIZE
__minix_mainjump:
/* unmap zero pages */
call __minix_unmapzero
call _main /* main(argc, argv, envp) */
push %eax /* push exit status */
call _exit
hlt /* force a trap if exit fails */
__minix_unmapzero:
/* unmap 0-page code */
push $I386_PAGE_SIZE
push $crtso
call _munmap_text /* unmap_text(crtso, I386_PAGE_SIZE) */
add $8, %esp
#ifdef __ACK__
/*
* ack uses separate segments for text and data by default. We have a
* common segment when compiling using any other compiler
*/
/* unmap 0-page data */
push $I386_PAGE_SIZE
push $romstart
call _munmap /* munmap(romstart, I386_PAGE_SIZE) */
add $8, %esp
#endif
ret
#ifdef __ACK__
.rom
romstart:
.space I386_PAGE_SIZE
__minix_datastart:
.space 4
#endif
.data
__penviron:
.long __penvp /* Pointer to environ, or hidden pointer */
.bss
.lcomm __penvp, 4 /* Hidden environment vector */
.lcomm __fpu_present, 4 /* FPU present flag */
.extern endtext /* Force loading of end labels. */

View file

@ -1,99 +0,0 @@
#
! This is the C run-time start-off routine. It's job is to take the
! arguments as put on the stack by EXEC, and to parse them and set them up the
! way _main expects them.
! It also initializes _environ when this variable isn't defined by the
! programmer. The detection of whether _environ belong to us is rather
! simplistic. We simply check for some magic value, but there is no other
! way.
#include <sys/vm_i386.h>
.sect .text; .sect .rom; .sect .data; .sect .bss
.define begtext, begdata, begbss
.sect .text
begtext:
.sect .rom
begrom:
.sect .data
begdata:
.sect .bss
begbss:
.define crtso, __penviron, __penvp, __fpu_present
.define __minix_datastart, __minix_mainjump, __minix_unmapzero
.extern _main, _exit
.sect .text
crtso:
xor ebp, ebp ! clear for backtrace of core files
mov eax, (esp) ! argc
lea edx, 4(esp) ! argv
lea ecx, 8(esp)(eax*4) ! envp
! Test if environ is in the initialized data area and is set to our
! magic number. If so then it is not redefined by the user.
mov ebx, _environ
cmp ebx, __edata ! within initialized data?
jae 0f
testb bl, 3 ! aligned?
jnz 0f
cmp (ebx), 0x53535353 ! is it our _environ?
jne 0f
mov (__penviron), ebx ! _penviron = &environ;
0: mov ebx, (__penviron)
mov (ebx), ecx ! *_penviron = envp;
push ecx ! push envp
push edx ! push argv
push eax ! push argc
! Test the EM bit of the MSW to determine if an FPU is present and
! set __fpu_present if one is found.
smsw ax
testb al, 0x4 ! EM bit in MSW
setz (__fpu_present) ! True if not set
jmp __minix_mainjump
.align I386_PAGE_SIZE
__minix_mainjump:
! unmap zero pages
call __minix_unmapzero
call _main ! main(argc, argv, envp)
push eax ! push exit status
call _exit
hlt ! force a trap if exit fails
__minix_unmapzero:
! unmap 0-page code
push I386_PAGE_SIZE
push crtso
call _munmap_text ! munmap_text(crtso, I386_PAGE_SIZE)
add esp, 8
! unmap 0-page data
push I386_PAGE_SIZE
push romstart
call _munmap ! munmap(romstart, I386_PAGE_SIZE)
add esp, 8
ret
.sect .rom
romstart:
.space I386_PAGE_SIZE
__minix_datastart:
.space 4
.sect .data
__penviron:
.data4 __penvp ! Pointer to environ, or hidden pointer
.sect .bss
.comm __penvp, 4 ! Hidden environment vector
.comm __fpu_present, 4 ! FPU present flag
.extern endtext ! Force loading of end labels.

View file

@ -2,15 +2,15 @@
.PATH: ${.CURDIR}/arch/${ARCH}/int64
SRCS+= \
add64.s \
add64u.s \
cmp64.s \
cv64u.s \
cvu64.s \
diff64.s \
div64u.s \
ex64.s \
make64.s \
mul64u.s \
sub64.s \
sub64u.s
add64.S \
add64u.S \
cmp64.S \
cv64u.S \
cvu64.S \
diff64.S \
div64u.S \
ex64.S \
make64.S \
mul64u.S \
sub64.S \
sub64u.S

View file

@ -0,0 +1,18 @@
/* add64() - 64 bit addition Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _add64
_add64:
/* u64_t add64(u64_t i, u64_t j); */
movl 4(%esp), %eax
movl 8(%esp), %edx
addl 16(%esp), %edx
movl %edx, (%eax)
movl 12(%esp), %edx
adcl 20(%esp), %edx
movl %edx, 4(%eax)
ret
/* */
/* $PchId: add64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,17 +0,0 @@
! add64() - 64 bit addition Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _add64
_add64: ! u64_t add64(u64_t i, u64_t j);
mov eax, 4(esp)
mov edx, 8(esp)
add edx, 16(esp)
mov (eax), edx
mov edx, 12(esp)
adc edx, 20(esp)
mov 4(eax), edx
ret
!
! $PchId: add64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,20 @@
/* add64u() - unsigned to 64 bit addition Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _add64u, _add64ul
_add64u:
/* u64_t add64u(u64_t i, unsigned j); */
_add64ul:
/* u64_t add64ul(u64_t i, unsigned long j); */
movl 4(%esp), %eax
movl 8(%esp), %edx
addl 16(%esp), %edx
movl %edx, (%eax)
movl 12(%esp), %edx
adcl $0, %edx
movl %edx, 4(%eax)
ret
/* */
/* $PchId: add64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,18 +0,0 @@
! add64u() - unsigned to 64 bit addition Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _add64u, _add64ul
_add64u: ! u64_t add64u(u64_t i, unsigned j);
_add64ul: ! u64_t add64ul(u64_t i, unsigned long j);
mov eax, 4(esp)
mov edx, 8(esp)
add edx, 16(esp)
mov (eax), edx
mov edx, 12(esp)
adc edx, 0
mov 4(eax), edx
ret
!
! $PchId: add64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,35 @@
/* cmp64*() - 64 bit compare Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _cmp64, _cmp64u, _cmp64ul
_cmp64:
/* int cmp64(u64_t i, u64_t j); */
movl %esp, %ecx
0:
xorl %eax, %eax
movl 4(%ecx), %edx
subl 12(%ecx), %edx
movl 8(%ecx), %edx
sbbl 16(%ecx), %edx
sbbl %eax, %eax /* eax = - (i < j) */
movl 12(%ecx), %edx
subl 4(%ecx), %edx
movl 16(%ecx), %edx
sbbl 8(%ecx), %edx
adcl $0, %eax /* eax = (i > j) - (i < j) */
ret
_cmp64u:
/* int cmp64u(u64_t i, unsigned j); */
_cmp64ul:
/* int cmp64ul(u64_t i, unsigned long j); */
movl %esp, %ecx
push 16(%ecx)
movl $0, 16(%ecx)
call 0b
pop 16(%ecx)
ret
/* */
/* $PchId: cmp64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,31 +0,0 @@
! cmp64*() - 64 bit compare Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _cmp64, _cmp64u, _cmp64ul
_cmp64: ! int cmp64(u64_t i, u64_t j);
mov ecx, esp
cmp64: xor eax, eax
mov edx, 4(ecx)
sub edx, 12(ecx)
mov edx, 8(ecx)
sbb edx, 16(ecx)
sbb eax, eax ! eax = - (i < j)
mov edx, 12(ecx)
sub edx, 4(ecx)
mov edx, 16(ecx)
sbb edx, 8(ecx)
adc eax, 0 ! eax = (i > j) - (i < j)
ret
_cmp64u: ! int cmp64u(u64_t i, unsigned j);
_cmp64ul: ! int cmp64ul(u64_t i, unsigned long j);
mov ecx, esp
push 16(ecx)
mov 16(ecx), 0
call cmp64
pop 16(ecx)
ret
!
! $PchId: cmp64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,18 @@
/* cv64u() - 64 bit converted to unsigned Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _cv64u, _cv64ul
_cv64u:
/* unsigned cv64u(u64_t i); */
_cv64ul:
/* unsigned long cv64ul(u64_t i); */
movl 4(%esp), %eax
cmpl $0, 8(%esp) /* return ULONG_MAX if really big */
je 0f
movl $-1, %eax
0:
ret
/* */
/* $PchId: cv64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,15 +0,0 @@
! cv64u() - 64 bit converted to unsigned Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _cv64u, _cv64ul
_cv64u: ! unsigned cv64u(u64_t i);
_cv64ul: ! unsigned long cv64ul(u64_t i);
mov eax, 4(esp)
cmp 8(esp), 0 ! return ULONG_MAX if really big
jz 0f
mov eax, -1
0: ret
!
! $PchId: cv64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,17 @@
/* cvu64() - unsigned converted to 64 bit Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _cvu64, _cvul64
_cvu64:
/* u64_t cvu64(unsigned i); */
_cvul64:
/* u64_t cvul64(unsigned long i); */
movl 4(%esp), %eax
movl 8(%esp), %edx
movl %edx, (%eax)
movl $0, 4(%eax)
ret
/* */
/* $PchId: cvu64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,15 +0,0 @@
! cvu64() - unsigned converted to 64 bit Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _cvu64, _cvul64
_cvu64: ! u64_t cvu64(unsigned i);
_cvul64: ! u64_t cvul64(unsigned long i);
mov eax, 4(esp)
mov edx, 8(esp)
mov (eax), edx
mov 4(eax), 0
ret
!
! $PchId: cvu64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,13 @@
/* diff64() - 64 bit subtraction giving unsigned Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _diff64
_diff64:
/* unsigned diff64(u64_t i, u64_t j); */
movl 4(%esp), %eax
subl 12(%esp), %eax
ret
/* */
/* $PchId: diff64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,12 +0,0 @@
! diff64() - 64 bit subtraction giving unsigned Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _diff64
_diff64: ! unsigned diff64(u64_t i, u64_t j);
mov eax, 4(esp)
sub eax, 12(esp)
ret
!
! $PchId: diff64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,24 @@
/* div64u() - 64 bit divided by unsigned giving unsigned long */
/* Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _div64u, _rem64u
_div64u:
/* unsigned long div64u(u64_t i, unsigned j); */
xorl %edx, %edx
movl 8(%esp), %eax /* i = (ih<<32) + il */
divl 12(%esp) /* ih = q * j + r */
movl 4(%esp), %eax
divl 12(%esp) /* i / j = (q<<32) + ((r<<32) + il) / j */
ret
_rem64u:
/* unsigned rem64u(u64_t i, unsigned j); */
pop %ecx
call _div64u
movl %edx, %eax
jmp *%ecx
/* */
/* $PchId: div64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,22 +0,0 @@
! div64u() - 64 bit divided by unsigned giving unsigned long
! Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _div64u, _rem64u
_div64u: ! unsigned long div64u(u64_t i, unsigned j);
xor edx, edx
mov eax, 8(esp) ! i = (ih<<32) + il
div 12(esp) ! ih = q * j + r
mov eax, 4(esp)
div 12(esp) ! i / j = (q<<32) + ((r<<32) + il) / j
ret
_rem64u: ! unsigned rem64u(u64_t i, unsigned j);
pop ecx
call _div64u
mov eax, edx
jmp ecx
!
! $PchId: div64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,18 @@
/* ex64*() - extract low or high 32 bits of a 64 bit number */
/* Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _ex64lo, _ex64hi
_ex64lo:
/* unsigned long ex64lo(u64_t i); */
movl 4(%esp), %eax
ret
_ex64hi:
/* unsigned long ex64hi(u64_t i); */
movl 8(%esp), %eax
ret
/* */
/* $PchId: ex64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,16 +0,0 @@
! ex64*() - extract low or high 32 bits of a 64 bit number
! Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _ex64lo, _ex64hi
_ex64lo: ! unsigned long ex64lo(u64_t i);
mov eax, 4(esp)
ret
_ex64hi: ! unsigned long ex64hi(u64_t i);
mov eax, 8(esp)
ret
!
! $PchId: ex64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,17 @@
/* make64() - make a 64 bit number from two 32 bit halves */
/* Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _make64
_make64:
/* u64_t make64(unsigned long lo, unsigned long hi); */
movl 4(%esp), %eax
movl 8(%esp), %edx
movl %edx, (%eax)
movl 12(%esp), %edx
movl %edx, 4(%eax)
ret
/* */
/* $PchId: make64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,16 +0,0 @@
! make64() - make a 64 bit number from two 32 bit halves
! Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _make64
_make64: ! u64_t make64(unsigned long lo, unsigned long hi);
mov eax, 4(esp)
mov edx, 8(esp)
mov (eax), edx
mov edx, 12(esp)
mov 4(eax), edx
ret
!
! $PchId: make64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,18 @@
/* mul64u() - unsigned long by unsigned multiply giving 64 bit result */
/* Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _mul64u
_mul64u:
/* u64_t mul64u(unsigned long i, unsigned j); */
movl 4(%esp), %ecx
movl 8(%esp), %eax
mull 12(%esp)
movl %eax, (%ecx)
movl %edx, 4(%ecx)
movl %ecx, %eax
ret
/* */
/* $PchId: mul64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,17 +0,0 @@
! mul64u() - unsigned long by unsigned multiply giving 64 bit result
! Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _mul64u
_mul64u: ! u64_t mul64u(unsigned long i, unsigned j);
mov ecx, 4(esp)
mov eax, 8(esp)
mul 12(esp)
mov (ecx), eax
mov 4(ecx), edx
mov eax, ecx
ret
!
! $PchId: mul64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,18 @@
/* sub64() - 64 bit subtraction Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _sub64
_sub64:
/* u64_t sub64(u64_t i, u64_t j); */
movl 4(%esp), %eax
movl 8(%esp), %edx
subl 16(%esp), %edx
movl %edx, (%eax)
movl 12(%esp), %edx
sbbl 20(%esp), %edx
movl %edx, 4(%eax)
ret
/* */
/* $PchId: sub64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,17 +0,0 @@
! sub64() - 64 bit subtraction Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _sub64
_sub64: ! u64_t sub64(u64_t i, u64_t j);
mov eax, 4(esp)
mov edx, 8(esp)
sub edx, 16(esp)
mov (eax), edx
mov edx, 12(esp)
sbb edx, 20(esp)
mov 4(eax), edx
ret
!
! $PchId: sub64.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -0,0 +1,20 @@
/* sub64() - unsigned from 64 bit subtraction Author: Kees J. Bot */
/* 7 Dec 1995 */
.text
.globl _sub64u, _sub64ul
_sub64u:
/* u64_t sub64u(u64_t i, unsigned j); */
_sub64ul:
/* u64_t sub64ul(u64_t i, unsigned long j); */
movl 4(%esp), %eax
movl 8(%esp), %edx
subl 16(%esp), %edx
movl %edx, (%eax)
movl 12(%esp), %edx
sbbl $0, %edx
movl %edx, 4(%eax)
ret
/* */
/* $PchId: sub64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $ */

View file

@ -1,18 +0,0 @@
! sub64() - unsigned from 64 bit subtraction Author: Kees J. Bot
! 7 Dec 1995
.sect .text
.define _sub64u, _sub64ul
_sub64u: ! u64_t sub64u(u64_t i, unsigned j);
_sub64ul: ! u64_t sub64ul(u64_t i, unsigned long j);
mov eax, 4(esp)
mov edx, 8(esp)
sub edx, 16(esp)
mov (eax), edx
mov edx, 12(esp)
sbb edx, 0
mov 4(eax), edx
ret
!
! $PchId: sub64u.ack.s,v 1.2 1996/04/11 18:59:57 philip Exp $

View file

@ -4,9 +4,9 @@
SRCS+= \
arch_compare.c \
arch_round.c \
fpu_cw.s \
fpu_sw.s \
fpu_round.s \
fpu_cw.S \
fpu_sw.S \
fpu_round.S \
fegetround.c \
feholdexcept.c \
fesetround.c

View file

@ -0,0 +1,20 @@
/* fpu_cw_get() - get FPU control word Author: Erik van der Kouwe */
/* fpu_cw_set() - set FPU control word 9 Dec 2009 */
.text
.globl _fpu_cw_get
.globl _fpu_cw_set
/* u16_t fpu_cw_get(void) */
_fpu_cw_get:
/* clear unused bits just to be sure */
xor %eax, %eax
push %eax
fstcw (%esp)
pop %eax
ret
/* void fpu_cw_set(u16_t fpu_cw) */
_fpu_cw_set:
/* load control word from parameter */
fldcw 4(%esp)
ret

View file

@ -1,20 +0,0 @@
! fpu_cw_get() - get FPU control word Author: Erik van der Kouwe
! fpu_cw_set() - set FPU control word 9 Dec 2009
.sect .text
.define _fpu_cw_get
.define _fpu_cw_set
! u16_t fpu_cw_get(void)
_fpu_cw_get:
! clear unused bits just to be sure
xor eax, eax
push eax
fstcw (esp)
pop eax
ret
! void fpu_cw_set(u16_t fpu_cw)
_fpu_cw_set:
! load control word from parameter
fldcw 4(esp)
ret

View file

@ -0,0 +1,37 @@
/* fpu_rndint() - round integer Author: Erik van der Kouwe */
/* 17 Dec 2009 */
.text
.globl _fpu_rndint
.globl _fpu_remainder
/* void fpu_rndint(double *value) */
_fpu_rndint:
/* move the value onto the floating point stack */
mov 4(%esp), %eax
fldl (%eax)
/* round it (beware of precision exception!) */
frndint
/* store the result */
fstpl (%eax)
ret
/* void fpu_remainder(double *x, double y) */
_fpu_remainder:
/* move the values onto the floating point stack */
fldl 8(%esp)
mov 4(%esp), %edx
fldl (%edx)
/* compute remainder, multiple iterations may be needed */
1:
fprem1
.byte 0xdf, 0xe0 /* fnstsw ax */
sahf
jp 1b
/* store the result and pop the divisor */
fstpl (%edx)
fstp %st
ret

View file

@ -1,36 +0,0 @@
! fpu_rndint() - round integer Author: Erik van der Kouwe
! 17 Dec 2009
.sect .text
.define _fpu_rndint
.define _fpu_remainder
! void fpu_rndint(double *value)
_fpu_rndint:
! move the value onto the floating point stack
mov eax, 4(esp)
fldd (eax)
! round it (beware of precision exception!)
frndint
! store the result
fstpd (eax)
ret
! void fpu_remainder(double *x, double y)
_fpu_remainder:
! move the values onto the floating point stack
fldd 8(esp)
mov edx, 4(esp)
fldd (edx)
! compute remainder, multiple iterations may be needed
1: fprem1
.data1 0xdf, 0xe0 ! fnstsw ax
sahf
jp 1b
! store the result and pop the divisor
fstpd (edx)
fstp st
ret

View file

@ -0,0 +1,37 @@
/* fpu_compare() - compare doubles Author: Erik van der Kouwe */
/* fpu_sw_get() - get FPU status 17 Dec 2009 */
/* fpu_xam() - examine double */
.text
.globl _fpu_compare
.globl _fpu_sw_get
.globl _fpu_xam
/* u16_t fpu_compare(double x, double y) */
_fpu_compare:
/* move the values onto the floating point stack */
fldl 12(%esp)
fldl 4(%esp)
/* compare values and return status word */
fcompp
jmp _fpu_sw_get
/* u16_t fpu_sw_get(void) */
_fpu_sw_get:
/* clear unused high-order word and get status word */
xor %eax, %eax
.byte 0xdf, 0xe0 /* fnstsw ax */
ret
/* u16_t fpu_xam(double value) */
_fpu_xam:
/* move the value onto the floating point stack */
fldl 4(%esp)
/* examine value and get status word */
fxam
call _fpu_sw_get
/* pop the value */
fstp %st
ret

View file

@ -1,38 +0,0 @@
! fpu_compare() - compare doubles Author: Erik van der Kouwe
! fpu_sw_get() - get FPU status 17 Dec 2009
! fpu_xam() - examine double
.sect .text
.define _fpu_compare
.define _fpu_sw_get
.define _fpu_xam
! u16_t fpu_compare(double x, double y)
_fpu_compare:
! move the values onto the floating point stack
fldd 12(esp)
fldd 4(esp)
! compare values and return status word
fcompp
jmp _fpu_sw_get
! u16_t fpu_sw_get(void)
_fpu_sw_get:
! clear unused high-order word and get status word
xor eax, eax
.data1 0xdf, 0xe0 ! fnstsw ax
ret
! u16_t fpu_xam(double value)
_fpu_xam:
! move the value onto the floating point stack
fldd 4(esp)
! examine value and get status word
fxam
call _fpu_sw_get
! pop the value
fstp st
ret

View file

@ -2,22 +2,22 @@
.PATH: ${.CURDIR}/arch/${ARCH}/misc
SRCS+= \
_cpuid.s \
_cpuid.S \
_cpufeature.c \
alloca.s \
get_bp.s \
getprocessor.s \
io_inb.s \
io_inl.s \
io_insb.s \
io_insl.s \
io_insw.s \
io_intr.s \
io_inw.s \
io_outb.s \
io_outl.s \
io_outsb.s \
io_outsl.s \
io_outsw.s \
io_outw.s \
oneC_sum.s
alloca.S \
get_bp.S \
getprocessor.S \
io_inb.S \
io_inl.S \
io_insb.S \
io_insl.S \
io_insw.S \
io_intr.S \
io_inw.S \
io_outb.S \
io_outl.S \
io_outsb.S \
io_outsl.S \
io_outsw.S \
io_outw.S \
oneC_sum.S

View file

@ -0,0 +1,41 @@
/* _cpuid() - interface to cpuid instruction */
/* void _cpuid(u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx); */
/* 0 for OK, nonzero for unsupported */
.globl __cpuid
.text
__cpuid:
/* save work registers */
push %ebp
push %ebx
/* set eax parameter to cpuid and execute cpuid */
movl 12(%esp), %ebp
mov (%ebp), %eax
movl 16(%esp), %ebp
mov (%ebp), %ebx
movl 20(%esp), %ebp
mov (%ebp), %ecx
movl 24(%esp), %ebp
mov (%ebp), %edx
.byte 0x0F, 0xA2 /* CPUID */
/* store results in pointer arguments */
movl 12(%esp), %ebp
movl %eax, (%ebp)
movl 16(%esp), %ebp
movl %ebx, (%ebp)
movl 20(%esp), %ebp
movl %ecx, (%ebp)
movl 24(%esp), %ebp
movl %edx, (%ebp)
/* restore registers */
pop %ebx
pop %ebp
ret

View file

@ -1,40 +0,0 @@
! _cpuid() - interface to cpuid instruction
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
! void _cpuid(u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx);
.define __cpuid
__cpuid:
! save registers
push ebp
push ebx
! set parameters to cpuid and execute cpuid
mov ebp, 12(esp)
mov eax, (ebp)
mov ebp, 16(esp)
mov ebx, (ebp)
mov ebp, 20(esp)
mov ecx, (ebp)
mov ebp, 24(esp)
mov edx, (ebp)
.data1 0x0F, 0xA2 ! CPUID
! store results in pointer arguments
mov ebp, 12(esp)
mov (ebp), eax
mov ebp, 16(esp)
mov (ebp), ebx
mov ebp, 20(esp)
mov (ebp), ecx
mov ebp, 24(esp)
mov (ebp), edx
! restore registers
pop ebx
pop ebp
ret

View file

@ -0,0 +1,32 @@
/* */
/* alloca() - allocate space on the stack Author: Kees J. Bot */
/* 2 Dec 1993 */
.text
.balign 16
.globl _alloca
_alloca:
#if __ACK__
pop %ecx /* Return address */
pop %eax /* Bytes to allocate */
addl $2*4+3, %eax /* Add space for two saved register variables */
andb $0xFC, %al /* Align */
movl %esp, %ebx /* Keep current esp */
subl %eax, %esp /* Lower stack */
movl %esp, %eax /* Return value */
push 4(%ebx) /* Push what is probably the saved esi */
push (%ebx) /* Saved edi */
/* Now ACK can still do: */
/* pop edi; pop esi; leave; ret */
push %eax /* Dummy argument */
jmp *%ecx
#else
pop %ecx /* Return address */
pop %eax /* Bytes to allocate */
addl $3, %eax
andb $0xFC, %al /* Align */
subl %eax, %esp /* Lower stack */
movl %esp, %eax /* Return value */
push %eax /* Dummy argument */
jmp *%ecx
#endif

View file

@ -1,33 +0,0 @@
#
! alloca() - allocate space on the stack Author: Kees J. Bot
! 2 Dec 1993
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.align 16
.define _alloca
_alloca:
#if __ACK__
pop ecx ! Return address
pop eax ! Bytes to allocate
add eax, 2*4+3 ! Add space for two saved register variables
andb al, 0xFC ! Align
mov ebx, esp ! Keep current esp
sub esp, eax ! Lower stack
mov eax, esp ! Return value
push 4(ebx) ! Push what is probably the saved esi
push (ebx) ! Saved edi
! Now ACK can still do:
! pop edi; pop esi; leave; ret
push eax ! Dummy argument
jmp ecx
#else
pop ecx ! Return address
pop eax ! Bytes to allocate
add eax, 3
andb al, 0xFC ! Align
sub esp, eax ! Lower stack
mov eax, esp ! Return value
push eax ! Dummy argument
jmp ecx
#endif

View file

@ -0,0 +1,14 @@
/* get_bp.s */
/* */
/* return EBP in EAX */
/* */
/* Created: Sep 7, 1992 by Philip Homburg */
.text
.globl _get_bp
_get_bp:
movl %ebp, %eax
ret
/* $PchId: get_bp.ack.s,v 1.3 1996/02/23 08:30:52 philip Exp $ */

View file

@ -1,16 +0,0 @@
! get_bp.s
!
! return EBP in EAX
!
! Created: Sep 7, 1992 by Philip Homburg
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define _get_bp
_get_bp:
mov eax, ebp
ret
! $PchId: get_bp.ack.s,v 1.3 1996/02/23 08:30:52 philip Exp $

View file

@ -0,0 +1,55 @@
/* getprocessor() - determine processor type Author: Kees J. Bot */
/* 26 Jan 1994 */
.text
/* int getprocessor(void); */
/* Return 386, 486, 586, ... */
.globl _getprocessor
_getprocessor:
push %ebp
movl %esp, %ebp
andl $0xFFFFFFFC, %esp /* Align stack to avoid AC fault */
movl $0x00040000, %ecx /* Try to flip the AC bit introduced on the 486 */
call flip
movl $386, %eax /* 386 if it didn't react to "flipping" */
je gotprocessor
movl $0x00200000, %ecx /* Try to flip the ID bit introduced on the 586 */
call flip
movl $486, %eax /* 486 if it didn't react */
je gotprocessor
pushf
pusha /* Save the world */
movl $1, %eax
.byte 0x0F, 0xA2 /* CPUID instruction tells the processor type */
andb $0x0F, %ah /* Extract the family (5, 6, ...) */
movzbl %ah, %eax
cmpl $15, %eax /* 15: extended family */
jne direct
movl $6, %eax /* Make it 686 */
direct:
imull $100, %eax /* 500, 600, ... */
addl $86, %eax /* 586, 686, ... */
movl %eax, 7*4(%esp) /* Pass eax through */
popa
popf
gotprocessor:
leave
ret
flip:
pushf /* Push eflags */
pop %eax /* eax = eflags */
movl %eax, %edx /* Save original eflags */
xorl %ecx, %eax /* Flip the bit to test */
push %eax /* Push modified eflags value */
popf /* Load modified eflags register */
pushf
pop %eax /* Get it again */
push %edx
popf /* Restore original eflags register */
xorl %edx, %eax /* See if the bit changed */
testl %ecx, %eax
ret

View file

@ -1,56 +0,0 @@
! getprocessor() - determine processor type Author: Kees J. Bot
! 26 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
! int getprocessor(void);
! Return 386, 486, 586, ...
.define _getprocessor
_getprocessor:
push ebp
mov ebp, esp
and esp, 0xFFFFFFFC ! Align stack to avoid AC fault
mov ecx, 0x00040000 ! Try to flip the AC bit introduced on the 486
call flip
mov eax, 386 ! 386 if it didn't react to "flipping"
jz gotprocessor
mov ecx, 0x00200000 ! Try to flip the ID bit introduced on the 586
call flip
mov eax, 486 ! 486 if it didn't react
jz gotprocessor
pushf
pusha ! Save the world
mov eax, 1
.data1 0x0F, 0xA2 ! CPUID instruction tells the processor type
andb ah, 0x0F ! Extract the family (5, 6, ...)
movzxb eax, ah
cmp eax, 15 ! 15: extended family
jne direct
mov eax, 6 ! Make it 686
direct:
imul eax, 100 ! 500, 600, ...
add eax, 86 ! 586, 686, ...
mov 7*4(esp), eax ! Pass eax through
popa
popf
gotprocessor:
leave
ret
flip:
pushf ! Push eflags
pop eax ! eax = eflags
mov edx, eax ! Save original eflags
xor eax, ecx ! Flip the bit to test
push eax ! Push modified eflags value
popf ! Load modified eflags register
pushf
pop eax ! Get it again
push edx
popf ! Restore original eflags register
xor eax, edx ! See if the bit changed
test eax, ecx
ret

View file

@ -0,0 +1,14 @@
/* inb() - Input one byte Author: Kees J. Bot */
/* 18 Mar 1996 */
/* unsigned inb(U16_t port); */
.text
.globl _inb
_inb:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %edx /* port */
xorl %eax, %eax
inb %dx /* read 1 byte */
pop %ebp
ret

View file

@ -1,14 +0,0 @@
! inb() - Input one byte Author: Kees J. Bot
! 18 Mar 1996
! unsigned inb(U16_t port);
.sect .text
.define _inb
_inb:
push ebp
mov ebp, esp
mov edx, 8(ebp) ! port
xor eax, eax
inb dx ! read 1 byte
pop ebp
ret

View file

@ -0,0 +1,13 @@
/* inl() - Input one dword Author: Kees J. Bot */
/* 18 Mar 1996 */
/* unsigned inl(U16_t port); */
.text
.globl _inl
_inl:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %edx /* port */
inl %dx /* read 1 dword */
pop %ebp
ret

View file

@ -1,13 +0,0 @@
! inl() - Input one dword Author: Kees J. Bot
! 18 Mar 1996
! unsigned inl(U16_t port);
.sect .text
.define _inl
_inl:
push ebp
mov ebp, esp
mov edx, 8(ebp) ! port
in dx ! read 1 dword
pop ebp
ret

View file

@ -0,0 +1,18 @@
/* insb() - Input a byte array Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void insb(U16_t port, void *buf, size_t count); */
.text
.globl _insb
_insb:
push %ebp
movl %esp, %ebp
cld
push %edi
movl 8(%ebp), %edx /* port */
movl 12(%ebp), %edi /* buf */
movl 16(%ebp), %ecx /* byte count */
rep insb /* input many bytes */
pop %edi
pop %ebp
ret

View file

@ -1,18 +0,0 @@
! insb() - Input a byte array Author: Kees J. Bot
! 18 Mar 1996
! void insb(U16_t port, void *buf, size_t count);
.sect .text
.define _insb
_insb:
push ebp
mov ebp, esp
cld
push edi
mov edx, 8(ebp) ! port
mov edi, 12(ebp) ! buf
mov ecx, 16(ebp) ! byte count
rep insb ! input many bytes
pop edi
pop ebp
ret

View file

@ -0,0 +1,19 @@
/* insl() - Input a dword array Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void insl(U16_t port, void *buf, size_t count); */
.text
.globl _insl
_insl:
push %ebp
movl %esp, %ebp
cld
push %edi
movl 8(%ebp), %edx /* port */
movl 12(%ebp), %edi /* buf */
movl 16(%ebp), %ecx /* byte count */
shrl $2, %ecx /* dword count */
rep insl /* input many dwords */
pop %edi
pop %ebp
ret

View file

@ -1,19 +0,0 @@
! insl() - Input a dword array Author: Kees J. Bot
! 18 Mar 1996
! void insl(U16_t port, void *buf, size_t count);
.sect .text
.define _insl
_insl:
push ebp
mov ebp, esp
cld
push edi
mov edx, 8(ebp) ! port
mov edi, 12(ebp) ! buf
mov ecx, 16(ebp) ! byte count
shr ecx, 2 ! dword count
rep ins ! input many dwords
pop edi
pop ebp
ret

View file

@ -0,0 +1,19 @@
/* insw() - Input a word array Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void insw(U16_t port, void *buf, size_t count); */
.text
.globl _insw
_insw:
push %ebp
movl %esp, %ebp
cld
push %edi
movl 8(%ebp), %edx /* port */
movl 12(%ebp), %edi /* buf */
movl 16(%ebp), %ecx /* byte count */
shrl $1, %ecx /* word count */
rep insw /* input many words */
pop %edi
pop %ebp
ret

View file

@ -1,19 +0,0 @@
! insw() - Input a word array Author: Kees J. Bot
! 18 Mar 1996
! void insw(U16_t port, void *buf, size_t count);
.sect .text
.define _insw
_insw:
push ebp
mov ebp, esp
cld
push edi
mov edx, 8(ebp) ! port
mov edi, 12(ebp) ! buf
mov ecx, 16(ebp) ! byte count
shr ecx, 1 ! word count
rep o16 ins ! input many words
pop edi
pop ebp
ret

View file

@ -0,0 +1,16 @@
/* intr_disable(), intr_enable - Disable/Enable hardware interrupts. */
/* Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void intr_disable(void); */
/* void intr_enable(void); */
.text
.globl _intr_disable
_intr_disable:
cli
ret
.globl _intr_enable
_intr_enable:
sti
ret

View file

@ -1,16 +0,0 @@
! intr_disable(), intr_enable - Disable/Enable hardware interrupts.
! Author: Kees J. Bot
! 18 Mar 1996
! void intr_disable(void);
! void intr_enable(void);
.sect .text
.define _intr_disable
_intr_disable:
cli
ret
.define _intr_enable
_intr_enable:
sti
ret

View file

@ -0,0 +1,14 @@
/* inw() - Input one word Author: Kees J. Bot */
/* 18 Mar 1996 */
/* unsigned inw(U16_t port); */
.text
.globl _inw
_inw:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %edx /* port */
xorl %eax, %eax
inw %dx /* read 1 word */
pop %ebp
ret

View file

@ -1,14 +0,0 @@
! inw() - Input one word Author: Kees J. Bot
! 18 Mar 1996
! unsigned inw(U16_t port);
.sect .text
.define _inw
_inw:
push ebp
mov ebp, esp
mov edx, 8(ebp) ! port
xor eax, eax
o16 in dx ! read 1 word
pop ebp
ret

View file

@ -0,0 +1,14 @@
/* outb() - Output one byte Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void outb(U16_t port, U8_t value); */
.text
.globl _outb
_outb:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %edx /* port */
movl 8+4(%ebp), %eax /* value */
outb %dx /* output 1 byte */
pop %ebp
ret

View file

@ -1,14 +0,0 @@
! outb() - Output one byte Author: Kees J. Bot
! 18 Mar 1996
! void outb(U16_t port, U8_t value);
.sect .text
.define _outb
_outb:
push ebp
mov ebp, esp
mov edx, 8(ebp) ! port
mov eax, 8+4(ebp) ! value
outb dx ! output 1 byte
pop ebp
ret

View file

@ -0,0 +1,14 @@
/* outl() - Output one dword Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void outl(U16_t port, u32_t value); */
.text
.globl _outl
_outl:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %edx /* port */
movl 8+4(%ebp), %eax /* value */
outl %dx /* output 1 dword */
pop %ebp
ret

View file

@ -1,14 +0,0 @@
! outl() - Output one dword Author: Kees J. Bot
! 18 Mar 1996
! void outl(U16_t port, u32_t value);
.sect .text
.define _outl
_outl:
push ebp
mov ebp, esp
mov edx, 8(ebp) ! port
mov eax, 8+4(ebp) ! value
out dx ! output 1 dword
pop ebp
ret

View file

@ -0,0 +1,18 @@
/* outsb() - Output a byte array Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void outsb(U16_t port, void *buf, size_t count); */
.text
.globl _outsb
_outsb:
push %ebp
movl %esp, %ebp
cld
push %esi
movl 8(%ebp), %edx /* port */
movl 12(%ebp), %esi /* buf */
movl 16(%ebp), %ecx /* byte count */
rep outsb /* output many bytes */
pop %esi
pop %ebp
ret

View file

@ -1,18 +0,0 @@
! outsb() - Output a byte array Author: Kees J. Bot
! 18 Mar 1996
! void outsb(U16_t port, void *buf, size_t count);
.sect .text
.define _outsb
_outsb:
push ebp
mov ebp, esp
cld
push esi
mov edx, 8(ebp) ! port
mov esi, 12(ebp) ! buf
mov ecx, 16(ebp) ! byte count
rep outsb ! output many bytes
pop esi
pop ebp
ret

View file

@ -0,0 +1,19 @@
/* outsl() - Output a dword array Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void outsl(U16_t port, void *buf, size_t count); */
.text
.globl _outsl
_outsl:
push %ebp
movl %esp, %ebp
cld
push %esi
movl 8(%ebp), %edx /* port */
movl 12(%ebp), %esi /* buf */
movl 16(%ebp), %ecx /* byte count */
shrl $2, %ecx /* dword count */
rep outsl /* output many dwords */
pop %esi
pop %ebp
ret

View file

@ -1,19 +0,0 @@
! outsl() - Output a dword array Author: Kees J. Bot
! 18 Mar 1996
! void outsl(U16_t port, void *buf, size_t count);
.sect .text
.define _outsl
_outsl:
push ebp
mov ebp, esp
cld
push esi
mov edx, 8(ebp) ! port
mov esi, 12(ebp) ! buf
mov ecx, 16(ebp) ! byte count
shr ecx, 2 ! dword count
rep outs ! output many dwords
pop esi
pop ebp
ret

View file

@ -0,0 +1,19 @@
/* outsw() - Output a word array Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void outsw(U16_t port, void *buf, size_t count); */
.text
.globl _outsw
_outsw:
push %ebp
movl %esp, %ebp
cld
push %esi
movl 8(%ebp), %edx /* port */
movl 12(%ebp), %esi /* buf */
movl 16(%ebp), %ecx /* byte count */
shrl $1, %ecx /* word count */
rep outsw /* output many words */
pop %esi
pop %ebp
ret

View file

@ -1,19 +0,0 @@
! outsw() - Output a word array Author: Kees J. Bot
! 18 Mar 1996
! void outsw(U16_t port, void *buf, size_t count);
.sect .text
.define _outsw
_outsw:
push ebp
mov ebp, esp
cld
push esi
mov edx, 8(ebp) ! port
mov esi, 12(ebp) ! buf
mov ecx, 16(ebp) ! byte count
shr ecx, 1 ! word count
rep o16 outs ! output many words
pop esi
pop ebp
ret

View file

@ -0,0 +1,14 @@
/* outw() - Output one word Author: Kees J. Bot */
/* 18 Mar 1996 */
/* void outw(U16_t port, U16_t value); */
.text
.globl _outw
_outw:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %edx /* port */
movl 8+4(%ebp), %eax /* value */
outw %dx /* output 1 word */
pop %ebp
ret

View file

@ -1,14 +0,0 @@
! outw() - Output one word Author: Kees J. Bot
! 18 Mar 1996
! void outw(U16_t port, U16_t value);
.sect .text
.define _outw
_outw:
push ebp
mov ebp, esp
mov edx, 8(ebp) ! port
mov eax, 8+4(ebp) ! value
o16 out dx ! output 1 word
pop ebp
ret

View file

@ -0,0 +1,91 @@
/* oneC_sum() - One complement`s checksum Author: Kees J. Bot */
/* 9 May 1995 */
/* See RFC 1071, "Computing the Internet checksum" */
/* See also the C version of this code. */
.text
.globl _oneC_sum
.balign 16
_oneC_sum:
push %ebp
movl %esp, %ebp
push %esi
push %edi
movzwl 8(%ebp), %eax /* Checksum of previous block */
movl 12(%ebp), %esi /* Data to compute checksum over */
movl 16(%ebp), %edi /* Number of bytes */
xorl %edx, %edx
xorb %cl, %cl
align:
testl $3, %esi /* Is the data aligned? */
je aligned
testl %edi, %edi
je 0f
movb (%esi), %dl /* Rotate the first unaligned bytes */
decl %edi /* into the edx register */
0:
incl %esi
rorl $8, %edx
rorl $8, %eax /* Rotate the checksum likewise */
addb $8, %cl /* Number of bits rotated */
jmp align
aligned:
addl %edx, %eax /* Summate the unaligned bytes */
adcl $0, %eax /* Add carry back in for one`s complement */
jmp add6test
.balign 16
add6:
addl (%esi), %eax /* Six times unrolled loop, see below */
adcl 4(%esi), %eax
adcl 8(%esi), %eax
adcl 12(%esi), %eax
adcl 16(%esi), %eax
adcl 20(%esi), %eax
adcl $0, %eax
addl $24, %esi
add6test:
subl $24, %edi
jae add6
addl $24, %edi
jmp add1test
.balign 16
add1:
addl (%esi), %eax /* while ((edi -= 4) >= 0) */
adcl $0, %eax /* eax += *esi++; */
addl $4, %esi /* edi += 4; */
add1test:
subl $4, %edi
jae add1
addl $4, %edi
je done /* Are there extra bytes? */
movl (%esi), %edx /* Load extra bytes in a full dword */
andl mask-4(,%edi,4), %edx /* Mask off excess */
addl %edx, %eax /* Add in the last bits */
adcl $0, %eax
done:
roll %cl, %eax /* Undo the rotation at the beginning */
movl %eax, %edx
shrl $16, %eax
addw %dx, %ax /* Add the two words in eax to form */
adcw $0, %ax /* a 16 bit sum */
pop %edi
pop %esi
pop %ebp
ret
#ifdef __ACK__
.rom
#else
.data
#endif
.balign 4
mask:
.long 0x000000FF, 0x0000FFFF, 0x00FFFFFF
/* */
/* $PchId: oneC_sum.ack.s,v 1.2 1996/03/12 19:33:51 philip Exp $ */

View file

@ -1,80 +0,0 @@
! oneC_sum() - One complement`s checksum Author: Kees J. Bot
! 9 May 1995
! See RFC 1071, "Computing the Internet checksum"
! See also the C version of this code.
.sect .text
.define _oneC_sum
.align 16
_oneC_sum:
push ebp
mov ebp, esp
push esi
push edi
movzx eax, 8(ebp) ! Checksum of previous block
mov esi, 12(ebp) ! Data to compute checksum over
mov edi, 16(ebp) ! Number of bytes
xor edx, edx
xorb cl, cl
align: test esi, 3 ! Is the data aligned?
jz aligned
test edi, edi
jz 0f
movb dl, (esi) ! Rotate the first unaligned bytes
dec edi ! into the edx register
0: inc esi
ror edx, 8
ror eax, 8 ! Rotate the checksum likewise
addb cl, 8 ! Number of bits rotated
jmp align
aligned:add eax, edx ! Summate the unaligned bytes
adc eax, 0 ! Add carry back in for one`s complement
jmp add6test
.align 16
add6: add eax, (esi) ! Six times unrolled loop, see below
adc eax, 4(esi)
adc eax, 8(esi)
adc eax, 12(esi)
adc eax, 16(esi)
adc eax, 20(esi)
adc eax, 0
add esi, 24
add6test:
sub edi, 24
jae add6
add edi, 24
jmp add1test
.align 16
add1: add eax, (esi) ! while ((edi -= 4) >= 0)
adc eax, 0 ! eax += *esi++;
add esi, 4 ! edi += 4;
add1test:
sub edi, 4
jae add1
add edi, 4
jz done ! Are there extra bytes?
mov edx, (esi) ! Load extra bytes in a full dword
and edx, mask-4(edi*4) ! Mask off excess
add eax, edx ! Add in the last bits
adc eax, 0
done: rol eax, cl ! Undo the rotation at the beginning
mov edx, eax
shr eax, 16
o16 add ax, dx ! Add the two words in eax to form
o16 adc ax, 0 ! a 16 bit sum
pop edi
pop esi
pop ebp
ret
.sect .rom
.align 4
mask: .data4 0x000000FF, 0x0000FFFF, 0x00FFFFFF
!
! $PchId: oneC_sum.ack.s,v 1.2 1996/03/12 19:33:51 philip Exp $

View file

@ -2,7 +2,7 @@
.PATH: ${.CURDIR}/arch/${ARCH}/rts
SRCS+= \
__sigreturn.s \
_ipc.s \
_senda.s \
brksize.s
__sigreturn.S \
_ipc.S \
_senda.S \
brksize.S

View file

@ -0,0 +1,9 @@
/* This routine is the low-level code for returning from signals. */
/* It calls __sigreturn, which is the normal "system call" routine. */
/* Both ___sigreturn and __sigreturn are needed. */
.text
.globl ___sigreturn
.extern __sigreturn
___sigreturn:
addl $16, %esp
jmp __sigreturn

View file

@ -1,10 +0,0 @@
! This routine is the low-level code for returning from signals.
! It calls __sigreturn, which is the normal "system call" routine.
! Both ___sigreturn and __sigreturn are needed.
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define ___sigreturn
.extern __sigreturn
___sigreturn:
add esp, 16
jmp __sigreturn

View file

@ -0,0 +1,83 @@
.globl __notify, __send, __senda, __sendnb, __receive, __sendrec, __do_kernel_call
/* See src/kernel/ipc.h for C definitions */
SEND = 1
RECEIVE = 2
SENDREC = 3
NOTIFY = 4
SENDNB = 5
IPCVEC = 33 /* ipc trap to kernel */
KERVEC = 32 /* syscall trap to kernel */
SRC_DST = 8 /* source/ destination process */
MESSAGE = 12 /* message pointer */
/**========================================================================* */
/* IPC assembly routines * */
/**========================================================================* */
/* all message passing routines save ebp, but destroy eax and ecx. */
.text
__send:
push %ebp
movl %esp, %ebp
push %ebx
movl SRC_DST(%ebp), %eax /* eax = dest-src */
movl MESSAGE(%ebp), %ebx /* ebx = message pointer */
movl $SEND, %ecx /* _send(dest, ptr) */
int $IPCVEC /* trap to the kernel */
pop %ebx
pop %ebp
ret
__receive:
push %ebp
movl %esp, %ebp
push %ebx
movl SRC_DST(%ebp), %eax /* eax = dest-src */
movl MESSAGE(%ebp), %ebx /* ebx = message pointer */
movl $RECEIVE, %ecx /* _receive(src, ptr) */
int $IPCVEC /* trap to the kernel */
pop %ebx
pop %ebp
ret
__sendrec:
push %ebp
movl %esp, %ebp
push %ebx
movl SRC_DST(%ebp), %eax /* eax = dest-src */
movl MESSAGE(%ebp), %ebx /* ebx = message pointer */
movl $SENDREC, %ecx /* _sendrec(srcdest, ptr) */
int $IPCVEC /* trap to the kernel */
pop %ebx
pop %ebp
ret
__notify:
push %ebp
movl %esp, %ebp
push %ebx
movl SRC_DST(%ebp), %eax /* eax = destination */
movl $NOTIFY, %ecx /* _notify(srcdst) */
int $IPCVEC /* trap to the kernel */
pop %ebx
pop %ebp
ret
__sendnb:
push %ebp
movl %esp, %ebp
push %ebx
movl SRC_DST(%ebp), %eax /* eax = dest-src */
movl MESSAGE(%ebp), %ebx /* ebx = message pointer */
movl $SENDNB, %ecx /* _sendnb(dest, ptr) */
int $IPCVEC /* trap to the kernel */
pop %ebx
pop %ebp
ret
__do_kernel_call:
/* pass the message pointer to kernel in the %eax register */
movl 4(%esp), %eax
int $KERVEC
ret

View file

@ -1,84 +0,0 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define __notify, __send, __senda, __sendnb, __receive, __sendrec, __do_kernel_call
! See src/kernel/ipc.h for C definitions
SEND = 1
RECEIVE = 2
SENDREC = 3
NOTIFY = 4
SENDNB = 5
IPCVEC = 33 ! ipc trap to kernel
KERVEC = 32 ! syscall trap to kernel
SRC_DST = 8 ! source/ destination process
MESSAGE = 12 ! message pointer
!*========================================================================*
! IPC assembly routines *
!*========================================================================*
! all message passing routines save ebp, but destroy eax and ecx.
.sect .text
__send:
push ebp
mov ebp, esp
push ebx
mov eax, SRC_DST(ebp) ! eax = dest-src
mov ebx, MESSAGE(ebp) ! ebx = message pointer
mov ecx, SEND ! _send(dest, ptr)
int IPCVEC ! trap to the kernel
pop ebx
pop ebp
ret
__receive:
push ebp
mov ebp, esp
push ebx
mov eax, SRC_DST(ebp) ! eax = dest-src
mov ebx, MESSAGE(ebp) ! ebx = message pointer
mov ecx, RECEIVE ! _receive(src, ptr)
int IPCVEC ! trap to the kernel
pop ebx
pop ebp
ret
__sendrec:
push ebp
mov ebp, esp
push ebx
mov eax, SRC_DST(ebp) ! eax = dest-src
mov ebx, MESSAGE(ebp) ! ebx = message pointer
mov ecx, SENDREC ! _sendrec(srcdest, ptr)
int IPCVEC ! trap to the kernel
pop ebx
pop ebp
ret
__notify:
push ebp
mov ebp, esp
push ebx
mov eax, SRC_DST(ebp) ! eax = destination
mov ecx, NOTIFY ! _notify(srcdst)
int IPCVEC ! trap to the kernel
pop ebx
pop ebp
ret
__sendnb:
push ebp
mov ebp, esp
push ebx
mov eax, SRC_DST(ebp) ! eax = dest-src
mov ebx, MESSAGE(ebp) ! ebx = message pointer
mov ecx, SENDNB ! _sendnb(dest, ptr)
int IPCVEC ! trap to the kernel
pop ebx
pop ebp
ret
__do_kernel_call:
! pass the message pointer to kernel in the %eax register
mov eax, 4(esp)
int KERVEC
ret

View file

@ -0,0 +1,21 @@
.globl __senda
SENDA = 16
SYSVEC = 33
MSGTAB = 8 /* message table */
TABCOUNT = 12 /* number of entries in message table */
.text
__senda:
push %ebp
movl %esp, %ebp
push %ebx
movl TABCOUNT(%ebp), %eax /* eax = count */
movl MSGTAB(%ebp), %ebx /* ebx = table */
movl $SENDA, %ecx /* _senda(table, count) */
int $SYSVEC /* trap to the kernel */
pop %ebx
pop %ebp
ret

View file

@ -1,22 +0,0 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define __senda
SENDA = 16
SYSVEC = 33
MSGTAB = 8 ! message table
TABCOUNT = 12 ! number of entries in message table
.sect .text
__senda:
push ebp
mov ebp, esp
push ebx
mov eax, TABCOUNT(ebp) ! eax = count
mov ebx, MSGTAB(ebp) ! ebx = table
mov ecx, SENDA ! _senda(table, count)
int SYSVEC ! trap to the kernel
pop ebx
pop ebp
ret

View file

@ -0,0 +1,5 @@
.globl __brksize
.data
.extern endbss, __brksize
__brksize:
.long endbss

View file

@ -1,5 +0,0 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define __brksize
.sect .data
.extern endbss, __brksize
__brksize: .data4 endbss

View file

@ -2,28 +2,28 @@
.PATH: ${.CURDIR}/arch/${ARCH}/string
SRCS+= \
_memmove.s \
_strncat.s \
_strncmp.s \
_strncpy.s \
_strnlen.s \
bcmp.s \
bcopy.s \
bzero.s \
index.s \
memchr.s \
memcmp.s \
memcpy.s \
memmove.s \
memset.s \
rindex.s \
strcat.s \
strchr.s \
strcmp.s \
strcpy.s \
strlen.s \
strncat.s \
strncmp.s \
strncpy.s \
strnlen.s \
strrchr.s
_memmove.S \
_strncat.S \
_strncmp.S \
_strncpy.S \
_strnlen.S \
bcmp.S \
bcopy.S \
bzero.S \
index.S \
memchr.S \
memcmp.S \
memcpy.S \
memmove.S \
memset.S \
rindex.S \
strcat.S \
strchr.S \
strcmp.S \
strcpy.S \
strlen.S \
strncat.S \
strncmp.S \
strncpy.S \
strnlen.S \
strrchr.S

View file

@ -0,0 +1,60 @@
/* _memmove() Author: Kees J. Bot */
/* 2 Jan 1994 */
/* void *_memmove(void *s1, const void *s2, size_t n) */
/* Copy a chunk of memory. Handle overlap. */
/* */
.text
.globl __memmove, __memcpy
.balign 16
__memmove:
push %ebp
movl %esp, %ebp
push %esi
push %edi
movl 8(%ebp), %edi /* String s1 */
movl 12(%ebp), %esi /* String s2 */
movl 16(%ebp), %ecx /* Length */
movl %edi, %eax
subl %esi, %eax
cmpl %ecx, %eax
jb downwards /* if (s2 - s1) < n then copy downwards */
__memcpy:
cld /* Clear direction bit: upwards */
cmpl $16, %ecx
jb upbyte /* Don't bother being smart with short arrays */
movl %esi, %eax
orl %edi, %eax
testb $1, %al
jne upbyte /* Bit 0 set, use byte copy */
testb $2, %al
jne upword /* Bit 1 set, use word copy */
uplword:
shrdl $2, %ecx, %eax /* Save low 2 bits of ecx in eax */
shrl $2, %ecx
rep movsl /* Copy longwords. */
shldl $2, %eax, %ecx /* Restore excess count */
upword:
shrl $1, %ecx
rep movsw /* Copy words */
adcl %ecx, %ecx /* One more byte? */
upbyte:
rep movsb /* Copy bytes */
done:
movl 8(%ebp), %eax /* Absolutely noone cares about this value */
pop %edi
pop %esi
pop %ebp
ret
/* Handle bad overlap by copying downwards, don't bother to do word copies. */
downwards:
std /* Set direction bit: downwards */
leal -1(%esi,%ecx,1), %esi
leal -1(%edi,%ecx,1), %edi
rep movsb /* Copy bytes */
cld
jmp done

View file

@ -1,58 +0,0 @@
! _memmove() Author: Kees J. Bot
! 2 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! void *_memmove(void *s1, const void *s2, size_t n)
! Copy a chunk of memory. Handle overlap.
!
.sect .text
.define __memmove, __memcpy
.align 16
__memmove:
push ebp
mov ebp, esp
push esi
push edi
mov edi, 8(ebp) ! String s1
mov esi, 12(ebp) ! String s2
mov ecx, 16(ebp) ! Length
mov eax, edi
sub eax, esi
cmp eax, ecx
jb downwards ! if (s2 - s1) < n then copy downwards
__memcpy:
cld ! Clear direction bit: upwards
cmp ecx, 16
jb upbyte ! Don't bother being smart with short arrays
mov eax, esi
or eax, edi
testb al, 1
jnz upbyte ! Bit 0 set, use byte copy
testb al, 2
jnz upword ! Bit 1 set, use word copy
uplword:shrd eax, ecx, 2 ! Save low 2 bits of ecx in eax
shr ecx, 2
rep
movs ! Copy longwords.
shld ecx, eax, 2 ! Restore excess count
upword: shr ecx, 1
rep
o16 movs ! Copy words
adc ecx, ecx ! One more byte?
upbyte: rep
movsb ! Copy bytes
done: mov eax, 8(ebp) ! Absolutely noone cares about this value
pop edi
pop esi
pop ebp
ret
! Handle bad overlap by copying downwards, don't bother to do word copies.
downwards:
std ! Set direction bit: downwards
lea esi, -1(esi)(ecx*1)
lea edi, -1(edi)(ecx*1)
rep
movsb ! Copy bytes
cld
jmp done

View file

@ -0,0 +1,41 @@
/* _strncat() Author: Kees J. Bot */
/* 1 Jan 1994 */
/* char *_strncat(char *s1, const char *s2, size_t edx) */
/* Append string s2 to s1. */
/* */
.text
.globl __strncat
.balign 16
__strncat:
push %ebp
movl %esp, %ebp
push %esi
push %edi
movl 8(%ebp), %edi /* String s1 */
movl $-1, %ecx
xorb %al, %al /* Null byte */
cld
repne scasb /* Look for the zero byte in s1 */
decl %edi /* Back one up (and clear 'Z' flag) */
push %edi /* Save end of s1 */
movl 12(%ebp), %edi /* edi = string s2 */
movl %edx, %ecx /* Maximum count */
repne scasb /* Look for the end of s2 */
jne no0
incl %ecx /* Exclude null byte */
no0:
subl %ecx, %edx /* Number of bytes in s2 */
movl %edx, %ecx
movl 12(%ebp), %esi /* esi = string s2 */
pop %edi /* edi = end of string s1 */
rep movsb /* Copy bytes */
stosb /* Add a terminating null */
movl 8(%ebp), %eax /* Return s1 */
pop %edi
pop %esi
pop %ebp
ret

View file

@ -1,41 +0,0 @@
! _strncat() Author: Kees J. Bot
! 1 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! char *_strncat(char *s1, const char *s2, size_t edx)
! Append string s2 to s1.
!
.sect .text
.define __strncat
.align 16
__strncat:
push ebp
mov ebp, esp
push esi
push edi
mov edi, 8(ebp) ! String s1
mov ecx, -1
xorb al, al ! Null byte
cld
repne
scasb ! Look for the zero byte in s1
dec edi ! Back one up (and clear 'Z' flag)
push edi ! Save end of s1
mov edi, 12(ebp) ! edi = string s2
mov ecx, edx ! Maximum count
repne
scasb ! Look for the end of s2
jne no0
inc ecx ! Exclude null byte
no0: sub edx, ecx ! Number of bytes in s2
mov ecx, edx
mov esi, 12(ebp) ! esi = string s2
pop edi ! edi = end of string s1
rep
movsb ! Copy bytes
stosb ! Add a terminating null
mov eax, 8(ebp) ! Return s1
pop edi
pop esi
pop ebp
ret

View file

@ -0,0 +1,35 @@
/* strncmp() Author: Kees J. Bot */
/* 1 Jan 1994 */
/* int strncmp(const char *s1, const char *s2, size_t ecx) */
/* Compare two strings. */
/* */
.text
.globl __strncmp
.balign 16
__strncmp:
push %ebp
movl %esp, %ebp
push %esi
push %edi
testl %ecx, %ecx /* Max length is zero? */
je done
movl 8(%ebp), %esi /* esi = string s1 */
movl 12(%ebp), %edi /* edi = string s2 */
cld
compare:
cmpsb /* Compare two bytes */
jne done
cmpb $0, -1(%esi) /* End of string? */
je done
decl %ecx /* Length limit reached? */
jne compare
done:
seta %al /* al = (s1 > s2) */
setb %ah /* ah = (s1 < s2) */
subb %ah, %al
movsbl %al, %eax /* eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 */
pop %edi
pop %esi
pop %ebp
ret

View file

@ -1,35 +0,0 @@
! strncmp() Author: Kees J. Bot
! 1 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! int strncmp(const char *s1, const char *s2, size_t ecx)
! Compare two strings.
!
.sect .text
.define __strncmp
.align 16
__strncmp:
push ebp
mov ebp, esp
push esi
push edi
test ecx, ecx ! Max length is zero?
je done
mov esi, 8(ebp) ! esi = string s1
mov edi, 12(ebp) ! edi = string s2
cld
compare:
cmpsb ! Compare two bytes
jne done
cmpb -1(esi), 0 ! End of string?
je done
dec ecx ! Length limit reached?
jne compare
done: seta al ! al = (s1 > s2)
setb ah ! ah = (s1 < s2)
subb al, ah
movsxb eax, al ! eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
pop edi
pop esi
pop ebp
ret

View file

@ -0,0 +1,23 @@
/* _strncpy() Author: Kees J. Bot */
/* 1 Jan 1994 */
/* char *_strncpy(char *s1, const char *s2, size_t ecx) */
/* Copy string s2 to s1. */
/* */
.text
.globl __strncpy
.balign 16
__strncpy:
movl 12(%ebp), %edi /* edi = string s2 */
xorb %al, %al /* Look for a zero byte */
movl %ecx, %edx /* Save maximum count */
cld
repne scasb /* Look for end of s2 */
subl %ecx, %edx /* Number of bytes in s2 including null */
xchgl %edx, %ecx
movl 12(%ebp), %esi /* esi = string s2 */
movl 8(%ebp), %edi /* edi = string s1 */
rep movsb /* Copy bytes */
ret

Some files were not shown because too many files have changed in this diff Show more