mirror of
https://github.com/zeldaret/oot.git
synced 2025-04-08 23:56:26 +00:00
[iQue] Match libgcc (#2412)
* [iQue] Match libgcc * Delete old stubs * Squash warning * Put GPL modification notice in libgcc2.inc.c too * Comment wording * Run clang-tidy on libgcc2.inc.c
This commit is contained in:
parent
62c0effccd
commit
5773b12241
27 changed files with 651 additions and 16 deletions
|
@ -1,6 +1,6 @@
|
|||
Checks: '-*,readability-braces-around-statements,readability-inconsistent-declaration-parameter-name'
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: '(src|include)\/.*\.h$'
|
||||
HeaderFilterRegex: '(src|include)\/.*(\.h|\.inc\.c)$'
|
||||
FormatStyle: 'file'
|
||||
CheckOptions:
|
||||
# Require argument names to match exactly (instead of allowing a name to be a prefix/suffix of another)
|
||||
|
|
15
spec
15
spec
|
@ -176,6 +176,21 @@ beginseg
|
|||
include "$(BUILD_DIR)/src/boot/build.o"
|
||||
include "$(BUILD_DIR)/data/rsp_boot.text.o"
|
||||
include "$(BUILD_DIR)/data/cic6105.text.o"
|
||||
|
||||
#if PLATFORM_IQUE && !defined(COMPILER_GCC)
|
||||
include "$(BUILD_DIR)/src/libgcc/__divdi3.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__moddi3.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__udivdi3.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__umoddi3.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__cmpdi2.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__floatdidf.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__floatdisf.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__fixunsdfdi.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__fixdfdi.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__fixunssfdi.o"
|
||||
include "$(BUILD_DIR)/src/libgcc/__fixsfdi.o"
|
||||
#endif
|
||||
|
||||
#ifdef COMPILER_GCC
|
||||
include "$(BUILD_DIR)/src/libc/memset.o"
|
||||
include "$(BUILD_DIR)/src/libc/memmove.o"
|
||||
|
|
2
src/libgcc/__cmpdi2.c
Normal file
2
src/libgcc/__cmpdi2.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_cmpdi2
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__divdi3.c
Normal file
2
src/libgcc/__divdi3.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_divdi3
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__fixdfdi.c
Normal file
2
src/libgcc/__fixdfdi.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_fixdfdi
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__fixsfdi.c
Normal file
2
src/libgcc/__fixsfdi.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_fixsfdi
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__fixunsdfdi.c
Normal file
2
src/libgcc/__fixunsdfdi.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_fixunsdfdi
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__fixunssfdi.c
Normal file
2
src/libgcc/__fixunssfdi.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_fixunssfdi
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__floatdidf.c
Normal file
2
src/libgcc/__floatdidf.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_floatdidf
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__floatdisf.c
Normal file
2
src/libgcc/__floatdisf.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_floatdisf
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__moddi3.c
Normal file
2
src/libgcc/__moddi3.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_moddi3
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__udivdi3.c
Normal file
2
src/libgcc/__udivdi3.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_udivdi3
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
2
src/libgcc/__umoddi3.c
Normal file
2
src/libgcc/__umoddi3.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define L_umoddi3
|
||||
#include "src/libgcc/libgcc2.inc.c"
|
464
src/libgcc/libgcc2.inc.c
Normal file
464
src/libgcc/libgcc2.inc.c
Normal file
|
@ -0,0 +1,464 @@
|
|||
/* More subroutines needed by GCC output code on some machines. */
|
||||
/* Compile this one with gcc. */
|
||||
/* Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with other files,
|
||||
some of which are compiled with GCC, to produce an executable,
|
||||
this library does not by itself cause the resulting executable
|
||||
to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
/* Modified by ZeldaRET to keep only the parts that are relevant to the iQue build of OoT. */
|
||||
|
||||
#include "ultra64/ultratypes.h"
|
||||
|
||||
typedef u8 UQItype;
|
||||
typedef s32 SItype;
|
||||
typedef u32 USItype;
|
||||
typedef s64 DItype;
|
||||
typedef u64 UDItype;
|
||||
|
||||
typedef f32 SFtype;
|
||||
typedef f64 DFtype;
|
||||
|
||||
typedef s32 word_type;
|
||||
|
||||
#define SI_TYPE_SIZE 32
|
||||
|
||||
#define DI_SIZE 64
|
||||
#define DF_SIZE 53
|
||||
#define SF_SIZE 24
|
||||
|
||||
#define WORD_SIZE 32
|
||||
#define HIGH_HALFWORD_COEFF (((UDItype)1) << (WORD_SIZE / 2))
|
||||
#define HIGH_WORD_COEFF (((UDItype)1) << WORD_SIZE)
|
||||
|
||||
/* DIstructs are pairs of SItype values in big-endian order. */
|
||||
|
||||
struct DIstruct {
|
||||
SItype high, low;
|
||||
};
|
||||
|
||||
/* We need this union to unpack/pack DImode values, since we don't have
|
||||
any arithmetic yet. Incoming DImode parameters are stored into the
|
||||
`ll' field, and the unpacked result is read from the struct `s'. */
|
||||
|
||||
typedef union {
|
||||
struct DIstruct s;
|
||||
DItype ll;
|
||||
} DIunion;
|
||||
|
||||
extern DItype __fixunssfdi(SFtype original_a);
|
||||
extern DItype __fixunsdfdi(DFtype a);
|
||||
|
||||
#if defined(L_divdi3) || defined(L_moddi3)
|
||||
static inline DItype __negdi2(DItype u) {
|
||||
DIunion w;
|
||||
DIunion uu;
|
||||
|
||||
uu.ll = u;
|
||||
|
||||
w.s.low = -uu.s.low;
|
||||
w.s.high = -uu.s.high - ((USItype)w.s.low > 0);
|
||||
|
||||
return w.ll;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_udivdi3) || defined(L_divdi3) || defined(L_umoddi3) || defined(L_moddi3)
|
||||
static const UQItype __clz_tab[] = {
|
||||
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
};
|
||||
|
||||
#include "src/libgcc/longlong.h"
|
||||
|
||||
static inline UDItype __udivmoddi4(UDItype n, UDItype d, UDItype* rp) {
|
||||
DIunion ww;
|
||||
DIunion nn, dd;
|
||||
DIunion rr;
|
||||
USItype d0, d1, n0, n1, n2;
|
||||
USItype q0, q1;
|
||||
USItype b, bm;
|
||||
|
||||
nn.ll = n;
|
||||
dd.ll = d;
|
||||
|
||||
d0 = dd.s.low;
|
||||
d1 = dd.s.high;
|
||||
n0 = nn.s.low;
|
||||
n1 = nn.s.high;
|
||||
|
||||
if (d1 == 0) {
|
||||
if (d0 > n1) {
|
||||
/* 0q = nn / 0D */
|
||||
|
||||
count_leading_zeros(bm, d0);
|
||||
|
||||
if (bm != 0) {
|
||||
/* Normalize, i.e. make the most significant bit of the
|
||||
denominator set. */
|
||||
|
||||
d0 = d0 << bm;
|
||||
n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
|
||||
n0 = n0 << bm;
|
||||
}
|
||||
|
||||
udiv_qrnnd(q0, n0, n1, n0, d0);
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in n0 >> bm. */
|
||||
} else {
|
||||
/* qq = NN / 0d */
|
||||
|
||||
if (d0 == 0) {
|
||||
d0 = 1 / d0; /* Divide intentionally by zero. */
|
||||
}
|
||||
|
||||
count_leading_zeros(bm, d0);
|
||||
|
||||
if (bm == 0) {
|
||||
/* From (n1 >= d0) /\ (the most significant bit of d0 is set),
|
||||
conclude (the most significant bit of n1 is set) /\ (the
|
||||
leading quotient digit q1 = 1).
|
||||
|
||||
This special case is necessary, not an optimization.
|
||||
(Shifts counts of SI_TYPE_SIZE are undefined.) */
|
||||
|
||||
n1 -= d0;
|
||||
q1 = 1;
|
||||
} else {
|
||||
/* Normalize. */
|
||||
|
||||
b = SI_TYPE_SIZE - bm;
|
||||
|
||||
d0 = d0 << bm;
|
||||
n2 = n1 >> b;
|
||||
n1 = (n1 << bm) | (n0 >> b);
|
||||
n0 = n0 << bm;
|
||||
|
||||
udiv_qrnnd(q1, n1, n2, n1, d0);
|
||||
}
|
||||
|
||||
/* n1 != d0... */
|
||||
|
||||
udiv_qrnnd(q0, n0, n1, n0, d0);
|
||||
|
||||
/* Remainder in n0 >> bm. */
|
||||
}
|
||||
|
||||
if (rp != 0) {
|
||||
rr.s.low = n0 >> bm;
|
||||
rr.s.high = 0;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
} else {
|
||||
if (d1 > n1) {
|
||||
/* 00 = nn / DD */
|
||||
|
||||
q0 = 0;
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in n1n0. */
|
||||
if (rp != 0) {
|
||||
rr.s.low = n0;
|
||||
rr.s.high = n1;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
} else {
|
||||
/* 0q = NN / dd */
|
||||
|
||||
count_leading_zeros(bm, d1);
|
||||
if (bm == 0) {
|
||||
/* From (n1 >= d1) /\ (the most significant bit of d1 is set),
|
||||
conclude (the most significant bit of n1 is set) /\ (the
|
||||
quotient digit q0 = 0 or 1).
|
||||
|
||||
This special case is necessary, not an optimization. */
|
||||
|
||||
/* The condition on the next line takes advantage of that
|
||||
n1 >= d1 (true due to program flow). */
|
||||
if (n1 > d1 || n0 >= d0) {
|
||||
q0 = 1;
|
||||
sub_ddmmss(n1, n0, n1, n0, d1, d0);
|
||||
} else {
|
||||
q0 = 0;
|
||||
}
|
||||
|
||||
q1 = 0;
|
||||
|
||||
if (rp != 0) {
|
||||
rr.s.low = n0;
|
||||
rr.s.high = n1;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
} else {
|
||||
USItype m1, m0;
|
||||
/* Normalize. */
|
||||
|
||||
b = SI_TYPE_SIZE - bm;
|
||||
|
||||
d1 = (d1 << bm) | (d0 >> b);
|
||||
d0 = d0 << bm;
|
||||
n2 = n1 >> b;
|
||||
n1 = (n1 << bm) | (n0 >> b);
|
||||
n0 = n0 << bm;
|
||||
|
||||
udiv_qrnnd(q0, n1, n2, n1, d1);
|
||||
umul_ppmm(m1, m0, q0, d0);
|
||||
|
||||
if (m1 > n1 || (m1 == n1 && m0 > n0)) {
|
||||
q0--;
|
||||
sub_ddmmss(m1, m0, m1, m0, d1, d0);
|
||||
}
|
||||
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in (n1n0 - m1m0) >> bm. */
|
||||
if (rp != 0) {
|
||||
sub_ddmmss(n1, n0, n1, n0, m1, m0);
|
||||
rr.s.low = (n1 << b) | (n0 >> bm);
|
||||
rr.s.high = n1 >> bm;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ww.s.low = q0;
|
||||
ww.s.high = q1;
|
||||
return ww.ll;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_divdi3
|
||||
DItype __divdi3(DItype u, DItype v) {
|
||||
word_type c = 0;
|
||||
DIunion uu, vv;
|
||||
DItype w;
|
||||
|
||||
uu.ll = u;
|
||||
vv.ll = v;
|
||||
|
||||
if (uu.s.high < 0) {
|
||||
c = ~c, uu.ll = __negdi2(uu.ll);
|
||||
}
|
||||
if (vv.s.high < 0) {
|
||||
c = ~c, vv.ll = __negdi2(vv.ll);
|
||||
}
|
||||
|
||||
w = __udivmoddi4(uu.ll, vv.ll, (UDItype*)0);
|
||||
if (c) {
|
||||
w = __negdi2(w);
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_moddi3
|
||||
DItype __moddi3(DItype u, DItype v) {
|
||||
word_type c = 0;
|
||||
DIunion uu, vv;
|
||||
DItype w;
|
||||
|
||||
uu.ll = u;
|
||||
vv.ll = v;
|
||||
|
||||
if (uu.s.high < 0) {
|
||||
c = ~c, uu.ll = __negdi2(uu.ll);
|
||||
}
|
||||
if (vv.s.high < 0) {
|
||||
vv.ll = __negdi2(vv.ll);
|
||||
}
|
||||
|
||||
(void)__udivmoddi4(uu.ll, vv.ll, (UDItype*)&w);
|
||||
if (c) {
|
||||
w = __negdi2(w);
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_umoddi3
|
||||
UDItype __umoddi3(UDItype u, UDItype v) {
|
||||
UDItype w;
|
||||
|
||||
(void)__udivmoddi4(u, v, &w);
|
||||
|
||||
return w;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_udivdi3
|
||||
UDItype __udivdi3(UDItype n, UDItype d) {
|
||||
return __udivmoddi4(n, d, (UDItype*)0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_cmpdi2
|
||||
word_type __cmpdi2(DItype a, DItype b) {
|
||||
DIunion au, bu;
|
||||
|
||||
au.ll = a, bu.ll = b;
|
||||
|
||||
if (au.s.high < bu.s.high) {
|
||||
return 0;
|
||||
} else if (au.s.high > bu.s.high) {
|
||||
return 2;
|
||||
}
|
||||
if ((USItype)au.s.low < (USItype)bu.s.low) {
|
||||
return 0;
|
||||
} else if ((USItype)au.s.low > (USItype)bu.s.low) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_fixunsdfdi
|
||||
DItype __fixunsdfdi(DFtype a) {
|
||||
DFtype b;
|
||||
UDItype v;
|
||||
|
||||
if (a < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute high word of result, as a flonum. */
|
||||
b = (a / HIGH_WORD_COEFF);
|
||||
/* Convert that to fixed (but not to DItype!),
|
||||
and shift it into the high word. */
|
||||
v = (USItype)b;
|
||||
v <<= WORD_SIZE;
|
||||
/* Remove high part from the DFtype, leaving the low part as flonum. */
|
||||
a -= (DFtype)v;
|
||||
/* Convert that to fixed (but not to DItype!) and add it in.
|
||||
Sometimes A comes out negative. This is significant, since
|
||||
A has more bits than a long int does. */
|
||||
if (a < 0) {
|
||||
v -= (USItype)(-a);
|
||||
} else {
|
||||
v += (USItype)a;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_fixdfdi
|
||||
DItype __fixdfdi(DFtype a) {
|
||||
if (a < 0) {
|
||||
return -__fixunsdfdi(-a);
|
||||
}
|
||||
return __fixunsdfdi(a);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_fixunssfdi
|
||||
DItype __fixunssfdi(SFtype original_a) {
|
||||
/* Convert the SFtype to a DFtype, because that is surely not going
|
||||
to lose any bits. Some day someone else can write a faster version
|
||||
that avoids converting to DFtype, and verify it really works right. */
|
||||
DFtype a = original_a;
|
||||
DFtype b;
|
||||
UDItype v;
|
||||
|
||||
if (a < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute high word of result, as a flonum. */
|
||||
b = (a / HIGH_WORD_COEFF);
|
||||
/* Convert that to fixed (but not to DItype!),
|
||||
and shift it into the high word. */
|
||||
v = (USItype)b;
|
||||
v <<= WORD_SIZE;
|
||||
/* Remove high part from the DFtype, leaving the low part as flonum. */
|
||||
a -= (DFtype)v;
|
||||
/* Convert that to fixed (but not to DItype!) and add it in.
|
||||
Sometimes A comes out negative. This is significant, since
|
||||
A has more bits than a long int does. */
|
||||
if (a < 0) {
|
||||
v -= (USItype)(-a);
|
||||
} else {
|
||||
v += (USItype)a;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_fixsfdi
|
||||
DItype __fixsfdi(SFtype a) {
|
||||
if (a < 0) {
|
||||
return -__fixunssfdi(-a);
|
||||
}
|
||||
return __fixunssfdi(a);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_floatdidf
|
||||
DFtype __floatdidf(DItype u) {
|
||||
DFtype d;
|
||||
|
||||
d = (SItype)(u >> WORD_SIZE);
|
||||
d *= HIGH_HALFWORD_COEFF;
|
||||
d *= HIGH_HALFWORD_COEFF;
|
||||
d += (USItype)(u & (HIGH_WORD_COEFF - 1));
|
||||
|
||||
return d;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_floatdisf
|
||||
SFtype __floatdisf(DItype u) {
|
||||
/* Do the calculation in DFmode
|
||||
so that we don't lose any of the precision of the high word
|
||||
while multiplying it. */
|
||||
DFtype f;
|
||||
|
||||
/* Protect against double-rounding error.
|
||||
Represent any low-order bits, that might be truncated in DFmode,
|
||||
by a bit that won't be lost. The bit can go in anywhere below the
|
||||
rounding position of the SFmode. A fixed mask and bit position
|
||||
handles all usual configurations. It doesn't handle the case
|
||||
of 128-bit DImode, however. */
|
||||
if (DF_SIZE < DI_SIZE && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE)) {
|
||||
#define REP_BIT ((USItype)1 << (DI_SIZE - DF_SIZE))
|
||||
if (!(-((DItype)1 << DF_SIZE) < u && u < ((DItype)1 << DF_SIZE))) {
|
||||
if ((USItype)u & (REP_BIT - 1)) {
|
||||
u |= REP_BIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
f = (SItype)(u >> WORD_SIZE);
|
||||
f *= HIGH_HALFWORD_COEFF;
|
||||
f *= HIGH_HALFWORD_COEFF;
|
||||
f += (USItype)(u & (HIGH_WORD_COEFF - 1));
|
||||
|
||||
return (SFtype)f;
|
||||
}
|
||||
#endif
|
149
src/libgcc/longlong.h
Normal file
149
src/libgcc/longlong.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
|
||||
Copyright (C) 1991, 92, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This definition file is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2, or (at your option) any later version.
|
||||
|
||||
This definition file is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Modified by ZeldaRET to keep only the parts that are relevant to the iQue build of OoT. */
|
||||
|
||||
#define __BITS4 (SI_TYPE_SIZE / 4)
|
||||
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
|
||||
#define __ll_lowpart(t) ((USItype)(t) % __ll_B)
|
||||
#define __ll_highpart(t) ((USItype)(t) / __ll_B)
|
||||
|
||||
/* Define auxiliary asm macros.
|
||||
|
||||
1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
|
||||
multiplies two USItype integers MULTIPLER and MULTIPLICAND,
|
||||
and generates a two-part USItype product in HIGH_PROD and
|
||||
LOW_PROD.
|
||||
|
||||
2) __umulsidi3(a,b) multiplies two USItype integers A and B,
|
||||
and returns a UDItype product. This is just a variant of umul_ppmm.
|
||||
|
||||
3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
|
||||
denominator) divides a two-word unsigned integer, composed by the
|
||||
integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
|
||||
places the quotient in QUOTIENT and the remainder in REMAINDER.
|
||||
HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
|
||||
If, in addition, the most significant bit of DENOMINATOR must be 1,
|
||||
then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
|
||||
|
||||
4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
|
||||
denominator). Like udiv_qrnnd but the numbers are signed. The
|
||||
quotient is rounded towards 0.
|
||||
|
||||
5) count_leading_zeros(count, x) counts the number of zero-bits from
|
||||
the msb to the first non-zero bit. This is the number of steps X
|
||||
needs to be shifted left to set the msb. Undefined for X == 0.
|
||||
|
||||
6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
|
||||
high_addend_2, low_addend_2) adds two two-word unsigned integers,
|
||||
composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
|
||||
LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and
|
||||
LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is
|
||||
lost.
|
||||
|
||||
7) sub_ddmmss(high_difference, low_difference, high_minuend,
|
||||
low_minuend, high_subtrahend, low_subtrahend) subtracts two
|
||||
two-word unsigned integers, composed by HIGH_MINUEND_1 and
|
||||
LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
|
||||
respectively. The result is placed in HIGH_DIFFERENCE and
|
||||
LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
|
||||
and is lost.
|
||||
|
||||
If any of these macros are left undefined for a particular CPU,
|
||||
C macros are used. */
|
||||
|
||||
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
|
||||
do { \
|
||||
USItype __x; \
|
||||
__x = (al) + (bl); \
|
||||
(sh) = (ah) + (bh) + (__x < (al)); \
|
||||
(sl) = __x; \
|
||||
} while (0)
|
||||
|
||||
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
|
||||
do { \
|
||||
USItype __x; \
|
||||
__x = (al) - (bl); \
|
||||
(sh) = (ah) - (bh) - (__x > (al)); \
|
||||
(sl) = __x; \
|
||||
} while (0)
|
||||
|
||||
#if __GNUC__ < 3
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
__asm__("multu %2,%3" : "=l"((USItype)(w0)), "=h"((USItype)(w1)) : "d"((USItype)(u)), "d"((USItype)(v)))
|
||||
#else
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
__asm__("multu %2,%3\n\t" \
|
||||
"mflo %0\n\t" \
|
||||
"mfhi %1" \
|
||||
: "=d"(w0), "=d"(w1) \
|
||||
: "d"((USItype)(u)), "d"((USItype)(v)))
|
||||
#endif
|
||||
|
||||
#define udiv_qrnnd(q, r, n1, n0, d) \
|
||||
do { \
|
||||
USItype __d1, __d0, __q1, __q0; \
|
||||
USItype __r1, __r0, __m; \
|
||||
__d1 = __ll_highpart(d); \
|
||||
__d0 = __ll_lowpart(d); \
|
||||
\
|
||||
__r1 = (n1) % __d1; \
|
||||
__q1 = (n1) / __d1; \
|
||||
__m = (USItype)__q1 * __d0; \
|
||||
__r1 = __r1 * __ll_B | __ll_highpart(n0); \
|
||||
if (__r1 < __m) { \
|
||||
__q1--, __r1 += (d); \
|
||||
if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */ \
|
||||
if (__r1 < __m) \
|
||||
__q1--, __r1 += (d); \
|
||||
} \
|
||||
__r1 -= __m; \
|
||||
\
|
||||
__r0 = __r1 % __d1; \
|
||||
__q0 = __r1 / __d1; \
|
||||
__m = (USItype)__q0 * __d0; \
|
||||
__r0 = __r0 * __ll_B | __ll_lowpart(n0); \
|
||||
if (__r0 < __m) { \
|
||||
__q0--, __r0 += (d); \
|
||||
if (__r0 >= (d)) \
|
||||
if (__r0 < __m) \
|
||||
__q0--, __r0 += (d); \
|
||||
} \
|
||||
__r0 -= __m; \
|
||||
\
|
||||
(q) = (USItype)__q1 * __ll_B | __q0; \
|
||||
(r) = __r0; \
|
||||
} while (0)
|
||||
|
||||
#define count_leading_zeros(count, x) \
|
||||
do { \
|
||||
USItype __xr = (x); \
|
||||
USItype __a; \
|
||||
\
|
||||
if (SI_TYPE_SIZE <= 32) { \
|
||||
__a = __xr < ((USItype)1 << 2 * __BITS4) \
|
||||
? (__xr < ((USItype)1 << __BITS4) ? 0 : __BITS4) \
|
||||
: (__xr < ((USItype)1 << 3 * __BITS4) ? 2 * __BITS4 : 3 * __BITS4); \
|
||||
} else { \
|
||||
for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
|
||||
if (((__xr >> __a) & 0xff) != 0) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
(count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
|
||||
} while (0)
|
|
@ -9,18 +9,3 @@ D_0F000000 = 0x0F000000;
|
|||
|
||||
// z_bg_mjin
|
||||
D_06000000 = 0x06000000;
|
||||
|
||||
#if PLATFORM_IQUE
|
||||
gzip_decompress = 0x80002C3C;
|
||||
__divdi3 = 0x80008010;
|
||||
__moddi3 = 0x800085F0;
|
||||
__udivdi3 = 0x80008B80;
|
||||
__umoddi3 = 0x800090F0;
|
||||
__cmpdi2 = 0x80009600;
|
||||
__floatdidf = 0x80009650;
|
||||
__floatdisf = 0x800096A0;
|
||||
__fixunsdfdi = 0x80009760;
|
||||
__fixdfdi = 0x80009960;
|
||||
__fixunssfdi = 0x800099D0;
|
||||
__fixsfdi = 0x80009BD0;
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue