mirror of
https://github.com/Interlisp/maiko.git
synced 2026-01-15 15:57:13 +00:00
Use gcc / clang overflow builtins. (#142)
* Use gcc / clang overflow builtins. This avoids expensive checks for overflow that employ undefined behavior. This is a step along the way towards replacing the old hand-written assembler that did the same thing in terms of using the CPU's overflow detection. * Remove unimplemented SPARC asm for multiplication, divide, and remainder. This wasn't implemented before, and for multiplication, it is now implemented for gcc and friends using overflow detection. * Remove USE_INLINE_ARITH. Now that we have the compiler built-ins for detecting overflow, we don't need custom assembly for it for each platform. For now, we keep, but still don't use, the code that do a hot path through the dispatch loop for some math. This code isn't actually running or in use, but it is separate from how the other inline arithmetic was being performed. These are the `fast_op_*` functions that are implemented in assembler.
This commit is contained in:
parent
36b8695bf6
commit
95b482d5d5
@ -228,7 +228,6 @@ SET(MAIKO_HDRS
|
||||
inc/adr68k.h
|
||||
inc/allocmdsdefs.h
|
||||
inc/arith2defs.h
|
||||
inc/arith2.h
|
||||
inc/arith3defs.h
|
||||
inc/arith4defs.h
|
||||
inc/arith.h
|
||||
|
||||
42
inc/arith.h
42
inc/arith.h
@ -154,29 +154,6 @@
|
||||
}
|
||||
|
||||
|
||||
/* Used in ISC asm inlines in arithmetic, to defeat optimizer.
|
||||
with INLINE_ERROR_EXIT, we use asm jumps to avoid having
|
||||
one or the other eliminated as dead code. */
|
||||
#ifdef ISC
|
||||
#define INLINE_ARITH_SWITCH(arg,retlbl) \
|
||||
switch(arg & 0xFFFF0000){ \
|
||||
case 0: \
|
||||
result=(S_POSITIVE | arg); \
|
||||
break; \
|
||||
case 0xFFFF0000: \
|
||||
result=(S_NEGATIVE | (0xFFFF & arg)); \
|
||||
break; \
|
||||
default:{register LispPTR *wordp; \
|
||||
/* arg is FIXP, call createcell */ \
|
||||
wordp = (LispPTR *) createcell68k(TYPE_FIXP); \
|
||||
*((int *)wordp) = arg; \
|
||||
result=(LADDR_from_68k(wordp)); \
|
||||
} \
|
||||
} \
|
||||
asm("jmp " retlbl)
|
||||
#endif /* ISC */
|
||||
|
||||
|
||||
#define N_IARITH_BODY_2(a, tos, op) \
|
||||
{ \
|
||||
register int arg1,arg2; \
|
||||
@ -220,23 +197,4 @@ do_ufn: ERROR_EXIT(a); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef I386
|
||||
|
||||
/*********************************************************/
|
||||
/* */
|
||||
/* Macros for arithmetic operations, to let inline work */
|
||||
/* */
|
||||
/*********************************************************/
|
||||
|
||||
#define iplus32(a,b) Xiplus32()
|
||||
#define plus32(a,b) Xplus32()
|
||||
#define iplus32n(a,b) Xiplus32n()
|
||||
#define sub32(a,b) Xsub32()
|
||||
#define isub32(a,b) Xisub32()
|
||||
#define sub32n(a,b) Xisub32n()
|
||||
#endif
|
||||
|
||||
#endif /* ARITH_H */
|
||||
|
||||
140
inc/arith2.h
140
inc/arith2.h
@ -1,140 +0,0 @@
|
||||
#ifndef ARITH2_H
|
||||
#define ARITH2_H 1
|
||||
/* $Id: arith2.h,v 1.2 1999/01/03 02:05:52 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved */
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* (C) Copyright 1989-92 Venue. All Rights Reserved. */
|
||||
/* Manufactured in the United States of America. */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Take care of results for inlined arithmetic cases. */
|
||||
/* xxx_RESULT does overflow checking and boxing. */
|
||||
/* */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
#ifdef ARITHINLINE
|
||||
#ifdef GCC386
|
||||
/* Inline defines for arith on GCC386 machines */
|
||||
|
||||
|
||||
extern inline const int plus32 (int arg1, int arg2)
|
||||
{
|
||||
asm(" addl %2,%0 \n\
|
||||
jo plus_err": "=r" (arg2): "0" (arg2), "r" (arg1));
|
||||
return arg2;
|
||||
}
|
||||
#define PLUS_RESULT \
|
||||
INLINE_ARITH_SWITCH(result,"plus_ret"); \
|
||||
asm("plus_err:"); \
|
||||
INLINE_ERROR_EXIT(tos,"plus_ret")
|
||||
|
||||
|
||||
|
||||
extern inline const int iplus32 (int arg1, int arg2)
|
||||
{
|
||||
asm(" addl %2,%0 \n\
|
||||
jo iplus_err": "=r" (arg2): "0" (arg2), "r" (arg1));
|
||||
return arg2;
|
||||
}
|
||||
#define IPLUS_RESULT \
|
||||
INLINE_ARITH_SWITCH(result,"iplus_ret"); \
|
||||
asm("iplus_err:"); \
|
||||
INLINE_ERROR_EXIT(tos,"iplus_ret")
|
||||
|
||||
|
||||
|
||||
extern inline const int sub32 (int arg1, int arg2)
|
||||
{
|
||||
asm("subl %2,%0 \n\
|
||||
jo diff_err": "=r" (arg1): "0" (arg1), "r" (arg2));
|
||||
return arg1;
|
||||
}
|
||||
#define DIFF_RESULT \
|
||||
INLINE_ARITH_SWITCH(result,"diff_ret"); \
|
||||
asm("diff_err:"); \
|
||||
INLINE_ERROR_EXIT(tos,"diff_ret")
|
||||
|
||||
|
||||
|
||||
extern inline const int isub32 (int arg1, int arg2)
|
||||
{
|
||||
asm(" subl %2,%0 \n\
|
||||
jo idiff_err": "=r" (arg1): "0" (arg1), "r" (arg2));
|
||||
return arg1;
|
||||
}
|
||||
#define IDIFF_RESULT \
|
||||
INLINE_ARITH_SWITCH(result,"idiff_ret"); \
|
||||
asm("idiff_err:"); \
|
||||
INLINE_ERROR_EXIT(tos,"idiff_ret")
|
||||
|
||||
|
||||
|
||||
extern inline const int iplus32n(int arg1, int arg2)
|
||||
{
|
||||
asm("addl %2,%0 \n\
|
||||
jo iplusn_err": "=r" (arg2): "0" (arg2), "r" (arg1));
|
||||
return arg2;
|
||||
}
|
||||
#define IPLUSN_RESULT \
|
||||
INLINE_ARITH_SWITCH(result,"iplusn_ret"); \
|
||||
asm("iplusn_err:"); \
|
||||
INLINE_ERROR_EXIT(tos,"iplusn_ret")
|
||||
|
||||
|
||||
|
||||
extern inline const int sub32n (int arg1, int arg2)
|
||||
{
|
||||
asm(" subl %2,%0 \n\
|
||||
jo idiffn_err": "=r" (arg1): "0" (arg1), "r" (arg2));
|
||||
return arg1;
|
||||
}
|
||||
#define IDIFFN_RESULT \
|
||||
INLINE_ARITH_SWITCH(result,"idiffn_ret"); \
|
||||
asm("idiffn_err:"); \
|
||||
INLINE_ERROR_EXIT(tos,"idiffn_ret")
|
||||
|
||||
|
||||
#else /* Any other ARITHINLINE case */
|
||||
|
||||
#define PLUS_RESULT \
|
||||
N_ARITH_SWITCH(result); \
|
||||
doufn2: plus_err_label(); \
|
||||
ERROR_EXIT(tos);
|
||||
|
||||
|
||||
#define IPLUS_RESULT \
|
||||
N_ARITH_SWITCH(result); \
|
||||
dummy: iplus_err_label();
|
||||
|
||||
|
||||
#define DIFF_RESULT \
|
||||
N_ARITH_SWITCH(result); \
|
||||
doufn2: diff_err_label(); \
|
||||
ERROR_EXIT(tos);
|
||||
|
||||
|
||||
#define IDIFF_RESULT \
|
||||
N_ARITH_SWITCH(result); \
|
||||
dummy: idiff_err_label();
|
||||
|
||||
|
||||
#define IPLUSN_RESULT \
|
||||
N_ARITH_SWITCH(result); \
|
||||
dummy: iplusn_err_label();
|
||||
|
||||
|
||||
#define IDIFFN_RESULT \
|
||||
N_ARITH_SWITCH(result); \
|
||||
dummy: idiffn_err_label();
|
||||
|
||||
#endif /* GCC386 */
|
||||
#endif /* ARITHINLINE */
|
||||
|
||||
#endif /* ARITH2_H */
|
||||
@ -483,10 +483,6 @@ DOSTACKOVERFLOW(argnum,bytenum) if it needs hardreturn-cleanup
|
||||
/************************************************************************/
|
||||
|
||||
#define ERROR_EXIT(tos) {TopOfStack=tos; Error_Exit = 1; return(-1);}
|
||||
#ifdef ISC
|
||||
#define INLINE_ERROR_EXIT(tos,retlbl) {TopOfStack=tos; Error_Exit=1 asm("movl $-1,%0\n" retlbl ":" : "=g" (result) : "0" (result)); return(result); }
|
||||
#endif
|
||||
|
||||
#define TIMER_EXIT(tos) {TopOfStack=tos; Error_Exit = 1; return(-2);}
|
||||
|
||||
|
||||
|
||||
@ -170,7 +170,6 @@ error Must specify RELEASE to build Medley.
|
||||
/* */
|
||||
/* Defaults: Unaligned fetches OK UNALIGNED_FETCH_OK */
|
||||
/* fp values used with */
|
||||
/* Use asm inline arith USE_INLINE_ARITH */
|
||||
/* pointer-wide unsigned UNSIGNED */
|
||||
/* pointer-wide int INT */
|
||||
/* */
|
||||
@ -192,12 +191,10 @@ error Must specify RELEASE to build Medley.
|
||||
|
||||
#ifdef SUN3_OS3_IL
|
||||
#define SUN3_OS3_OR_OS4_IL 1
|
||||
#define USE_INLINE_ARITH 1
|
||||
#endif
|
||||
|
||||
#ifdef SUN3_OS4_IL
|
||||
#define SUN3_OS3_OR_OS4_IL 1
|
||||
#define USE_INLINE_ARITH 1
|
||||
#endif
|
||||
|
||||
|
||||
@ -220,6 +217,16 @@ error Must specify RELEASE to build Medley.
|
||||
|
||||
|
||||
|
||||
/********************************************************/
|
||||
/* */
|
||||
/********************************************************/
|
||||
#ifdef __GNUC__
|
||||
#define USE_OVERFLOW_BUILTINS
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************************************/
|
||||
/* */
|
||||
/********************************************************/
|
||||
@ -232,13 +239,6 @@ error Must specify RELEASE to build Medley.
|
||||
|
||||
|
||||
|
||||
/********************************************************/
|
||||
/* */
|
||||
/********************************************************/
|
||||
#ifdef I386
|
||||
#define USE_INLINE_ARITH 1
|
||||
#endif /* I386 */
|
||||
|
||||
/********************************************************/
|
||||
/* */
|
||||
/********************************************************/
|
||||
|
||||
80
src/arith2.c
80
src/arith2.c
@ -31,28 +31,26 @@ N_OP_plus2
|
||||
************************************************************/
|
||||
|
||||
LispPTR N_OP_plus2(int tosm1, int tos) {
|
||||
register int arg1, arg2;
|
||||
register int result;
|
||||
int arg1, arg2;
|
||||
int result;
|
||||
|
||||
N_GETNUMBER(tos, arg1, doufn);
|
||||
N_GETNUMBER(tosm1, arg2, doufn);
|
||||
|
||||
#ifdef USE_INLINE_ARITH
|
||||
#ifdef USE_OVERFLOW_BUILTINS
|
||||
|
||||
result = plus32(arg1, arg2);
|
||||
if (__builtin_sadd_overflow(arg1, arg2, &result)) {
|
||||
ERROR_EXIT(tos);
|
||||
}
|
||||
N_ARITH_SWITCH(result);
|
||||
|
||||
doufn2:
|
||||
plus_err_label();
|
||||
ERROR_EXIT(tos);
|
||||
|
||||
#else
|
||||
/* UB: signed integer overflow: 2147483647 + 2147483647 cannot be represented in type 'int' */
|
||||
result = arg1 + arg2;
|
||||
if (((arg1 >= 0) == (arg2 >= 0)) && ((result >= 0) != (arg1 >= 0))) { ERROR_EXIT(tos); }
|
||||
N_ARITH_SWITCH(result);
|
||||
|
||||
#endif /* USE_INLINE_ARITH */
|
||||
#endif
|
||||
|
||||
doufn:
|
||||
return (N_OP_fplus2(tosm1, tos));
|
||||
@ -68,18 +66,18 @@ doufn:
|
||||
/************************************************************************/
|
||||
|
||||
LispPTR N_OP_iplus2(int tosm1, int tos) {
|
||||
register int arg1, arg2;
|
||||
register int result;
|
||||
int arg1, arg2;
|
||||
int result;
|
||||
|
||||
N_IGETNUMBER(tos, arg1, doufn);
|
||||
N_IGETNUMBER(tosm1, arg2, doufn);
|
||||
|
||||
#ifdef USE_INLINE_ARITH
|
||||
#ifdef USE_OVERFLOW_BUILTINS
|
||||
|
||||
result = iplus32(arg1, arg2);
|
||||
if (__builtin_sadd_overflow(arg1, arg2, &result)) {
|
||||
ERROR_EXIT(tos);
|
||||
}
|
||||
N_ARITH_SWITCH(result);
|
||||
dummy:
|
||||
iplus_err_label();
|
||||
|
||||
#else
|
||||
|
||||
@ -88,7 +86,7 @@ dummy:
|
||||
if (((arg1 >= 0) == (arg2 >= 0)) && ((result >= 0) != (arg1 >= 0))) { ERROR_EXIT(tos); }
|
||||
N_ARITH_SWITCH(result);
|
||||
|
||||
#endif /* USE_INLINE_ARITH */
|
||||
#endif
|
||||
|
||||
doufn:
|
||||
ERROR_EXIT(tos);
|
||||
@ -102,21 +100,19 @@ N_OP_difference
|
||||
************************************************************/
|
||||
|
||||
LispPTR N_OP_difference(int tosm1, int tos) {
|
||||
register int arg1, arg2;
|
||||
register int result;
|
||||
int arg1, arg2;
|
||||
int result;
|
||||
|
||||
N_GETNUMBER(tosm1, arg1, doufn);
|
||||
N_GETNUMBER(tos, arg2, doufn);
|
||||
|
||||
#ifdef USE_INLINE_ARITH
|
||||
#ifdef USE_OVERFLOW_BUILTINS
|
||||
|
||||
result = sub32(arg1, arg2);
|
||||
if (__builtin_ssub_overflow(arg1, arg2, &result)) {
|
||||
ERROR_EXIT(tos);
|
||||
}
|
||||
N_ARITH_SWITCH(result);
|
||||
|
||||
doufn2:
|
||||
diff_err_label();
|
||||
ERROR_EXIT(tos);
|
||||
|
||||
#else
|
||||
|
||||
/* UB: signed integer overflow: -2147483647 - 320 cannot be represented in type 'int' */
|
||||
@ -131,18 +127,18 @@ doufn:
|
||||
}
|
||||
|
||||
LispPTR N_OP_idifference(int tosm1, int tos) {
|
||||
register int arg1, arg2;
|
||||
register int result;
|
||||
int arg1, arg2;
|
||||
int result;
|
||||
|
||||
N_IGETNUMBER(tosm1, arg1, doufn);
|
||||
N_IGETNUMBER(tos, arg2, doufn);
|
||||
|
||||
#ifdef USE_INLINE_ARITH
|
||||
#ifdef USE_OVERFLOW_BUILTINS
|
||||
|
||||
result = isub32(arg1, arg2);
|
||||
if (__builtin_ssub_overflow(arg1, arg2, &result)) {
|
||||
ERROR_EXIT(tos);
|
||||
}
|
||||
N_ARITH_SWITCH(result);
|
||||
dummy:
|
||||
idiff_err_label();
|
||||
|
||||
#else
|
||||
/* UB: signed integer overflow: -2147483647 - 100 cannot be represented in type 'int' */
|
||||
@ -220,17 +216,17 @@ N_OP_iplusn
|
||||
return(tos + n)
|
||||
************************************************************/
|
||||
LispPTR N_OP_iplusn(int tos, int n) {
|
||||
register int arg1;
|
||||
register int result;
|
||||
int arg1;
|
||||
int result;
|
||||
|
||||
N_IGETNUMBER(tos, arg1, do_ufn);
|
||||
|
||||
#ifdef USE_INLINE_ARITH
|
||||
#ifdef USE_OVERFLOW_BUILTINS
|
||||
|
||||
result = iplus32n(arg1, n);
|
||||
if (__builtin_sadd_overflow(arg1, n, &result)) {
|
||||
ERROR_EXIT(tos);
|
||||
}
|
||||
N_ARITH_SWITCH(result);
|
||||
dummy:
|
||||
iplusn_err_label();
|
||||
|
||||
#else
|
||||
|
||||
@ -250,17 +246,17 @@ N_OP_idifferencen
|
||||
return(tos - n)
|
||||
************************************************************/
|
||||
LispPTR N_OP_idifferencen(int tos, int n) {
|
||||
register int arg1;
|
||||
register int result;
|
||||
int arg1;
|
||||
int result;
|
||||
|
||||
N_IGETNUMBER(tos, arg1, do_ufn);
|
||||
|
||||
#ifdef USE_INLINE_ARITH
|
||||
#ifdef USE_OVERFLOW_BUILTINS
|
||||
|
||||
result = sub32n(arg1, n);
|
||||
if (__builtin_ssub_overflow(arg1, n, &result)) {
|
||||
ERROR_EXIT(tos);
|
||||
}
|
||||
N_ARITH_SWITCH(result);
|
||||
dummy:
|
||||
idiffn_err_label();
|
||||
|
||||
#else
|
||||
|
||||
|
||||
61
src/arith4.c
61
src/arith4.c
@ -44,18 +44,18 @@
|
||||
*/
|
||||
/**********************************************************************/
|
||||
int N_OP_times2(int tosm1, int tos) {
|
||||
register int arg1, arg2;
|
||||
register int result;
|
||||
int arg1, arg2;
|
||||
int result;
|
||||
|
||||
N_GETNUMBER(tosm1, arg1, doufn);
|
||||
N_GETNUMBER(tos, arg2, doufn);
|
||||
|
||||
#ifdef SUN3_OS3_OR_OS4_IL
|
||||
#ifdef USE_OVERFLOW_BUILTINS
|
||||
|
||||
result = mpy32(arg1, arg2);
|
||||
if (__builtin_smul_overflow(arg1, arg2, &result)) {
|
||||
goto doufn2;
|
||||
}
|
||||
N_ARITH_SWITCH(result);
|
||||
dummy:
|
||||
mpy_err_label();
|
||||
|
||||
#else
|
||||
|
||||
@ -73,18 +73,18 @@ doufn:
|
||||
} /* end N_OP_times2 */
|
||||
|
||||
int N_OP_itimes2(int tosm1, int tos) {
|
||||
register int arg1, arg2;
|
||||
register int result;
|
||||
int arg1, arg2;
|
||||
int result;
|
||||
|
||||
N_IGETNUMBER(tosm1, arg1, doufn);
|
||||
N_IGETNUMBER(tos, arg2, doufn);
|
||||
|
||||
#ifdef SUN3_OS3_OR_OS4_IL
|
||||
#ifdef USE_OVERFLOW_BUILTINS
|
||||
|
||||
result = impy32(arg1, arg2);
|
||||
if (__builtin_smul_overflow(arg1, arg2, &result)) {
|
||||
goto doufn;
|
||||
}
|
||||
N_ARITH_SWITCH(result);
|
||||
dummy:
|
||||
impy_err_label();
|
||||
|
||||
#else
|
||||
|
||||
@ -108,25 +108,16 @@ doufn:
|
||||
*/
|
||||
/**********************************************************************/
|
||||
int N_OP_quot(int tosm1, int tos) {
|
||||
register int arg1, arg2;
|
||||
register int result;
|
||||
int arg1, arg2;
|
||||
int result;
|
||||
|
||||
N_GETNUMBER(tosm1, arg1, doufn);
|
||||
N_GETNUMBER(tos, arg2, doufn);
|
||||
if (arg2 == 0) goto doufn2;
|
||||
|
||||
#ifdef SUN3_OS3_OR_OS4_IL
|
||||
|
||||
result = quot32(arg1, arg2);
|
||||
N_ARITH_SWITCH(result);
|
||||
dummy:
|
||||
quot_err_label();
|
||||
|
||||
#else
|
||||
|
||||
result = arg1 / arg2; /* lmm: note: no error case!! */
|
||||
N_ARITH_SWITCH(result);
|
||||
#endif
|
||||
|
||||
doufn2:
|
||||
ERROR_EXIT(tos);
|
||||
doufn:
|
||||
@ -142,20 +133,9 @@ int N_OP_iquot(int tosm1, int tos) {
|
||||
N_IGETNUMBER(tos, arg2, doufn);
|
||||
if (arg2 == 0) goto doufn;
|
||||
|
||||
#ifdef SUN3_OS3_OR_OS4_IL
|
||||
|
||||
result = iquot32(arg1, arg2);
|
||||
N_ARITH_SWITCH(result);
|
||||
dummy:
|
||||
iquot_err_label();
|
||||
|
||||
#else
|
||||
|
||||
result = arg1 / arg2;
|
||||
N_ARITH_SWITCH(result);
|
||||
|
||||
#endif
|
||||
|
||||
doufn:
|
||||
ERROR_EXIT(tos);
|
||||
|
||||
@ -177,20 +157,9 @@ int N_OP_iremainder(int tosm1, int tos) {
|
||||
N_IGETNUMBER(tos, arg2, doufn);
|
||||
if (arg2 == 0) goto doufn;
|
||||
|
||||
#ifdef SUN3_OS3_OR_OS4_IL
|
||||
|
||||
result = irem32(arg1, arg2);
|
||||
N_ARITH_SWITCH(result);
|
||||
dummy:
|
||||
irem_err_label();
|
||||
|
||||
#else
|
||||
|
||||
result = arg1 % arg2;
|
||||
N_ARITH_SWITCH(result);
|
||||
|
||||
#endif
|
||||
|
||||
doufn:
|
||||
ERROR_EXIT(tos);
|
||||
|
||||
|
||||
@ -142,54 +142,6 @@
|
||||
jmp *optable(,%eax,4)
|
||||
.end
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
//
|
||||
// Arithmetic code speedups
|
||||
//
|
||||
// Assume edi & esi are arguments
|
||||
//
|
||||
// ebx is result.
|
||||
//
|
||||
////////////////////////////////
|
||||
|
||||
.inline Xiplus32,0
|
||||
addl %edi,%esi
|
||||
jo iplus_err
|
||||
movl %esi,%eax
|
||||
.end
|
||||
|
||||
.inline Xiplus32n,0
|
||||
leal (%edi),%eax
|
||||
addl %esi,%eax
|
||||
jo iplusn_err
|
||||
.end
|
||||
|
||||
|
||||
.inline Xplus32,0
|
||||
leal (%edi),%eax
|
||||
addl %esi,%eax
|
||||
jo plus_err
|
||||
.end
|
||||
|
||||
.inline Xsub32,0
|
||||
leal (%edi),%eax
|
||||
subl %esi,%eax
|
||||
jo diff_err
|
||||
.end
|
||||
|
||||
.inline Xisub32,0
|
||||
leal (%edi),%eax
|
||||
subl %esi,%eax
|
||||
jo idiff_err
|
||||
.end
|
||||
|
||||
.inline Xisub32n,0
|
||||
leal (%edi),%eax
|
||||
subl %esi,%eax
|
||||
jo idiffn_err
|
||||
.end
|
||||
|
||||
.inline plus_err_label,0
|
||||
plus_err:
|
||||
.end
|
||||
|
||||
@ -131,80 +131,6 @@ done: ! else done;
|
||||
nop
|
||||
.end
|
||||
|
||||
/*
|
||||
***************************************************************
|
||||
Arithmetic Opcode Helpers
|
||||
***************************************************************
|
||||
*/
|
||||
|
||||
.inline _sub32,8
|
||||
subcc %o0,%o1,%o0 ! result = arg0 - arg1
|
||||
bvs diff_err
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _isub32,8
|
||||
subcc %o0,%o1,%o0 ! result = arg0 - arg1
|
||||
bvs idiff_err
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _sub32n,8
|
||||
subcc %o0,%o1,%o0 ! result = arg0 - arg1
|
||||
bvs diff_err2
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _mpy32,8
|
||||
ba mpy_err
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _impy32,8
|
||||
ba impy_err
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _quot32,8
|
||||
ba quot_err
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _iquot32,8
|
||||
ba iquot_err
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _rem32,8
|
||||
ba rem_err
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _irem32,8
|
||||
ba irem_err
|
||||
nop
|
||||
.end
|
||||
|
||||
|
||||
.inline _plus32,8
|
||||
addcc %o0,%o1,%o0 ! result = arg0 + arg1
|
||||
bvs plus_err
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _iplus32,8
|
||||
addcc %o0,%o1,%o0 ! result = arg0 + arg1
|
||||
bvs iplus_err
|
||||
nop
|
||||
.end
|
||||
|
||||
.inline _iplus32n,8
|
||||
addcc %o0,%o1,%o0 ! result = arg0 + arg1
|
||||
bvs iplusn_err
|
||||
nop
|
||||
.end
|
||||
|
||||
|
||||
/*
|
||||
***************************************************************
|
||||
Inline Assembly help for dispatcher.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user