Skip to content

Commit

Permalink
eabi32 and eabi64 support (#5)
Browse files Browse the repository at this point in the history
* add eabi to the makefile

* eabi support

* Fix -Wexpansion-to-defined

* Add eabi builds to CI

* changelog

* fix abi guard
  • Loading branch information
AngheloAlf authored Nov 14, 2023
1 parent b970687 commit 1b07dbc
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 15 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ jobs:
- {
ABI: n64
}
- {
ABI: eabi32
}
- {
ABI: eabi64
}

name: Building for ABI ${{ matrix.TARGET.ABI }}
steps:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- `libc` functions:
- Memory functions: `memcpy`, `memmove`.
- Support for more ABIs: `eabi32` and `eabi64`

## [v0.1.0] - 2023-11-07

Expand Down
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ SHELL = /bin/bash
# n64
TARGET_ABI ?= o32

ifneq ($(TARGET_ABI),$(filter $(TARGET_ABI), o32 n32 o64 n64))
$(error Need to invoke make with a valid TARGET_ABI variable, like `make TARGET_ABI=o32`. Valid ABIs: o32, n32, o64, n64)
ifneq ($(TARGET_ABI),$(filter $(TARGET_ABI), o32 n32 o64 n64 eabi32 eabi64))
$(error Need to invoke make with a valid TARGET_ABI variable, like `make TARGET_ABI=o32`. Valid ABIs: o32, n32, o64, n64, eabi32, eabi64)
endif


Expand Down Expand Up @@ -77,6 +77,10 @@ OBJDUMP_FLAGS += -Mreg-names=64
else ifeq ($(TARGET_ABI),n64)
ABI := -mabi=64
OBJDUMP_FLAGS += -Mreg-names=64
else ifeq ($(TARGET_ABI),eabi32)
ABI := -mabi=eabi -mgp32 -mfp32
else ifeq ($(TARGET_ABI),eabi64)
ABI := -mabi=eabi -mgp64 -mfp64
endif


Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ required by the tested games.
- All the functions provided by this library are marked as `weak` functions in
the case the user provides their own implementations for some of the
functions of this library and wants to use those instead.
- Compatible with various ABIs: `o32`, `n32`, `o64`, `n64`.
- Compatible with various ABIs: `o32`, `n32`, `o64`, `n64`, `eabi32` and
`eabi64`.

## Why I made this?

Expand Down Expand Up @@ -104,7 +105,7 @@ make TARGET_ABI=ABI
```

Change `ABI` to the desired ABI to build. The supported values for `ABI` are
`o32`, `n32`, `o64` and `n64`.
`o32`, `n32`, `o64`, `n64`, `eabi32` and `eabi64`.

To use a different GCC cross compiler, pass `CROSS=` with the prefix of the
toolchain. For example `CROSS=mips-linux-gnu-`.
Expand Down
40 changes: 40 additions & 0 deletions include/gcc_vr4300/abi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef GCC_VR4300_ABI_H
#define GCC_VR4300_ABI_H

#if (defined(_MIPS_SIM) && (_MIPS_SIM == _ABIO32))
#define ABI_O32 1
#else
#define ABI_O32 0
#endif

#if (defined(_MIPS_SIM) && (_MIPS_SIM == _ABIN32))
#define ABI_N32 1
#else
#define ABI_N32 0
#endif

#if (defined(_MIPS_SIM) && (_MIPS_SIM == _ABIO64))
#define ABI_O64 1
#else
#define ABI_O64 0
#endif

#if (defined(_MIPS_SIM) && (_MIPS_SIM == _ABI64))
#define ABI_N64 1
#else
#define ABI_N64 0
#endif

#if (defined(__mips_eabi) && __mips_eabi && !defined(__mips64))
#define ABI_EABI32 1
#else
#define ABI_EABI32 0
#endif

#if (defined(__mips_eabi) && __mips_eabi && defined(__mips64) && __mips64)
#define ABI_EABI64 1
#else
#define ABI_EABI64 0
#endif

#endif
13 changes: 11 additions & 2 deletions include/gcc_vr4300/hasm.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#ifndef GCC_VR4300_H
#define GCC_VR4300_H
#ifndef GCC_VR4300_HASM_H
#define GCC_VR4300_HASM_H

#include "version.h"
#include "abi.h"

#define LEAF(x) \
.align 2 ;\
Expand All @@ -19,4 +20,12 @@
.ident "libgcc_vr4300 " LIBGCC_VR4300_VER_STRING; \
.ident "https://github.com/Decompollaborate/libgcc_vr4300"

#if ABI_EABI32
#define ASM_STACK_START addiu $sp, $sp, -0x10
#define ASM_STACK_END addiu $sp, $sp, 0x10
#else
#define ASM_STACK_START
#define ASM_STACK_END
#endif

#endif
3 changes: 2 additions & 1 deletion include/gcc_vr4300/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define GCC_VR4300_TYPES_H

#include "macro.h"
#include "abi.h"

typedef __SIZE_TYPE__ size_t;

Expand All @@ -18,7 +19,7 @@ STATIC_ASSERT(sizeof(float32) == 4, "float32 type's size is not 4");
typedef double float64;
STATIC_ASSERT(sizeof(float64) == 8, "float64 type's size is not 8");

#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
#if ABI_N32 || ABI_N64
typedef long double float128;
STATIC_ASSERT(sizeof(float128) == 16, "float128 type's size is not 16");
#endif
Expand Down
12 changes: 10 additions & 2 deletions src/soft_int/division/__divdi3.s
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ int64_t __divdi3(int64_t numerator, int64_t denominator) {

// https://gcc.gnu.org/onlinedocs/gccint/the-gcc-low-level-runtime-library/routines-for-integer-arithmetic.html#_CPPv49__divdi3mm
LEAF(__divdi3)
#if _MIPS_SIM == _ABIO32
#if ABI_O32 || ABI_EABI32

ASM_STACK_START

// store numerator pair into stack
sw $a0, 0x0($sp)
Expand All @@ -45,18 +47,24 @@ ddiv $v0, $t0, $t1
dsll32 $v1, $v0, 0
dsra32 $v1, $v1, 0

ASM_STACK_END

// set $v0 to the upper 32 bits of the quotient
jr $ra
dsra32 $v0, $v0, 0

#elif _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABIO64 || _MIPS_SIM == _ABI64
#elif ABI_N32 || ABI_O64 || ABI_N64 || ABI_EABI64

// get the quotient into $v0
ddiv $v0, $a0, $a1

jr $ra
nop

#else

#error "Unsupported ABI detected"

#endif
END(__divdi3)

Expand Down
12 changes: 10 additions & 2 deletions src/soft_int/division/__udivdi3.s
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ uint64_t __udivdi3(uint64_t numerator, uint64_t denominator) {

// https://gcc.gnu.org/onlinedocs/gccint/the-gcc-low-level-runtime-library/routines-for-integer-arithmetic.html#_CPPv49__udivdi3mm
LEAF(__udivdi3)
#if _MIPS_SIM == _ABIO32
#if ABI_O32 || ABI_EABI32

ASM_STACK_START

// store numerator pair into stack
sw $a0, 0x0($sp)
Expand All @@ -45,18 +47,24 @@ ddivu $v0, $t0, $t1
dsll32 $v1, $v0, 0
dsra32 $v1, $v1, 0

ASM_STACK_END

// set $v0 to the upper 32 bits of the quotient
jr $ra
dsra32 $v0, $v0, 0

#elif _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABIO64 || _MIPS_SIM == _ABI64
#elif ABI_N32 || ABI_O64 || ABI_N64 || ABI_EABI64

// get the quotient into $v0 (unsigned)
ddivu $v0, $a0, $a1

jr $ra
nop

#else

#error "Unsupported ABI detected"

#endif
END(__udivdi3)

Expand Down
12 changes: 10 additions & 2 deletions src/soft_int/reminder/__moddi3.s
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ int64_t __moddi3(int64_t numerator, int64_t denominator) {

// https://gcc.gnu.org/onlinedocs/gccint/the-gcc-low-level-runtime-library/routines-for-integer-arithmetic.html#_CPPv49__moddi3mm
LEAF(__moddi3)
#if _MIPS_SIM == _ABIO32
#if ABI_O32 || ABI_EABI32

ASM_STACK_START

// store numerator pair into stack
sw $a0, 0x0($sp)
Expand All @@ -45,18 +47,24 @@ drem $v0, $t0, $t1
dsll32 $v1, $v0, 0
dsra32 $v1, $v1, 0

ASM_STACK_END

// set $v0 to the upper 32 bits of the reminder
jr $ra
dsra32 $v0, $v0, 0

#elif _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABIO64 || _MIPS_SIM == _ABI64
#elif ABI_N32 || ABI_O64 || ABI_N64 || ABI_EABI64

// get the reminder into $v0
drem $v0, $a0, $a1

jr $ra
nop

#else

#error "Unsupported ABI detected"

#endif
END(__moddi3)

Expand Down
12 changes: 10 additions & 2 deletions src/soft_int/reminder/__umoddi3.s
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ uint64_t __umoddi3(uint64_t numerator, uint64_t denominator) {

// https://gcc.gnu.org/onlinedocs/gccint/the-gcc-low-level-runtime-library/routines-for-integer-arithmetic.html#_CPPv49__umoddi3mm
LEAF(__umoddi3)
#if _MIPS_SIM == _ABIO32
#if ABI_O32 || ABI_EABI32

ASM_STACK_START

// store numerator pair into stack
sw $a0, 0x0($sp)
Expand All @@ -45,18 +47,24 @@ dremu $v0, $t0, $t1
dsll32 $v1, $v0, 0
dsra32 $v1, $v1, 0

ASM_STACK_END

// set $v0 to the upper 32 bits of the reminder
jr $ra
dsra32 $v0, $v0, 0

#elif _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABIO64 || _MIPS_SIM == _ABI64
#elif ABI_N32 || ABI_O64 || ABI_N64 || ABI_EABI64

// get the reminder into $v0 (unsigned)
dremu $v0, $a0, $a1

jr $ra
nop

#else

#error "Unsupported ABI detected"

#endif
END(__umoddi3)

Expand Down

0 comments on commit 1b07dbc

Please sign in to comment.