summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-01-26 20:43:22 -0500
committerBen Gamari <ben@smart-cactus.org>2022-01-29 14:52:56 -0500
commitc6bede69443a9f40b0504cee83d9b2c5e9b8163b (patch)
tree63a4f37b4cd0c993cc3e6d434b5575ea44b9bbe8
parentd85a527f493c0ed41736cf6220a4291a26769d50 (diff)
downloadhaskell-c6bede69443a9f40b0504cee83d9b2c5e9b8163b.tar.gz
rts: Rip out SPARC support
-rw-r--r--libraries/ghci/GHCi/InfoTable.hsc22
-rw-r--r--rts/StgCRun.c75
-rw-r--r--rts/adjustor/NativeSparc.c106
-rw-r--r--rts/include/stg/SMP.h3
-rw-r--r--rts/linker/Elf.c75
-rw-r--r--rts/rts.cabal.in2
-rw-r--r--rts/sm/GCTDecl.h20
7 files changed, 10 insertions, 293 deletions
diff --git a/libraries/ghci/GHCi/InfoTable.hsc b/libraries/ghci/GHCi/InfoTable.hsc
index 9cc9ac1557..d92a2f0fbb 100644
--- a/libraries/ghci/GHCi/InfoTable.hsc
+++ b/libraries/ghci/GHCi/InfoTable.hsc
@@ -67,28 +67,6 @@ funPtrToInt (FunPtr a) = I## (addr2Int## a)
mkJumpToAddr :: MonadFail m => EntryFunPtr-> m ItblCodes
mkJumpToAddr a = case hostPlatformArch of
- ArchSPARC -> pure $
- -- After some consideration, we'll try this, where
- -- 0x55555555 stands in for the address to jump to.
- -- According to rts/include/rts/MachRegs.h, %g3 is very
- -- likely indeed to be baggable.
- --
- -- 0000 07155555 sethi %hi(0x55555555), %g3
- -- 0004 8610E155 or %g3, %lo(0x55555555), %g3
- -- 0008 81C0C000 jmp %g3
- -- 000c 01000000 nop
-
- let w32 = fromIntegral (funPtrToInt a)
-
- hi22, lo10 :: Word32 -> Word32
- lo10 x = x .&. 0x3FF
- hi22 x = (x `shiftR` 10) .&. 0x3FFFF
-
- in Right [ 0x07000000 .|. (hi22 w32),
- 0x8610E000 .|. (lo10 w32),
- 0x81C0C000,
- 0x01000000 ]
-
ArchPPC -> pure $
-- We'll use r12, for no particular reason.
-- 0xDEADBEEF stands for the address:
diff --git a/rts/StgCRun.c b/rts/StgCRun.c
index 25a931994d..8e536ad6c2 100644
--- a/rts/StgCRun.c
+++ b/rts/StgCRun.c
@@ -36,7 +36,7 @@
#define ENABLE_UNWINDING
#endif
-#if defined(sparc_HOST_ARCH) || defined(USE_MINIINTERPRETER)
+#if defined(USE_MINIINTERPRETER)
/* include Stg.h first because we want real machine regs in here: we
* have to get the value of R1 back from Stg land to C land intact.
*/
@@ -564,79 +564,6 @@ StgRunIsImplementedInAssembler(void)
#endif /* x86-64 */
-/* -----------------------------------------------------------------------------
- Sparc architecture
-
- --
- OLD COMMENT from GHC-3.02:
-
- We want tailjumps to be calls, because `call xxx' is the only Sparc
- branch that allows an arbitrary label as a target. (Gcc's ``goto
- *target'' construct ends up loading the label into a register and
- then jumping, at the cost of two extra instructions for the 32-bit
- load.)
-
- When entering the threaded world, we stash our return address in a
- known location so that \tr{%i7} is available as an extra
- callee-saves register. Of course, we have to restore this when
- coming out of the threaded world.
-
- I hate this god-forsaken architecture. Since the top of the
- reserved stack space is used for globals and the bottom is reserved
- for outgoing arguments, we have to stick our return address
- somewhere in the middle. Currently, I'm allowing 100 extra
- outgoing arguments beyond the first 6. --JSM
-
- Updated info (GHC 4.06): we don't appear to use %i7 any more, so
- I'm not sure whether we still need to save it. Incedentally, what
- does the last paragraph above mean when it says "the top of the
- stack is used for globals"? What globals? --SDM
-
- Updated info (GHC 4.08.2): not saving %i7 any more (see below).
- -------------------------------------------------------------------------- */
-
-#if defined(sparc_HOST_ARCH)
-
-StgRegTable *
-StgRun(StgFunPtr f, StgRegTable *basereg) {
-
- unsigned char space[RESERVED_C_STACK_BYTES];
-#if 0
- register void *i7 __asm__("%i7");
- ((void **)(space))[100] = i7;
-#endif
- f();
- __asm__ volatile (
- ".align 4\n"
- ".global " STG_RETURN "\n"
- STG_RETURN ":"
- : : "p" (space) : "l0","l1","l2","l3","l4","l5","l6","l7");
- /* we tell the C compiler that l0-l7 are clobbered on return to
- * StgReturn, otherwise it tries to use these to save eg. the
- * address of space[100] across the call. The correct thing
- * to do would be to save all the callee-saves regs, but we
- * can't be bothered to do that.
- *
- * We also explicitly mark space as used since gcc eliminates it
- * otherwise.
- *
- * The code that gcc generates for this little fragment is now
- * terrible. We could do much better by coding it directly in
- * assembler.
- */
-#if 0
- /* updated 4.08.2: we don't save %i7 in the middle of the reserved
- * space any more, since gcc tries to save its address across the
- * call to f(), this gets clobbered in STG land and we end up
- * dereferencing a bogus pointer in StgReturn.
- */
- __asm__ volatile ("ld %1,%0"
- : "=r" (i7) : "m" (((void **)(space))[100]));
-#endif
- return (StgRegTable *)R1.i;
-}
-
-#endif
/* -----------------------------------------------------------------------------
PowerPC architecture
diff --git a/rts/adjustor/NativeSparc.c b/rts/adjustor/NativeSparc.c
deleted file mode 100644
index 52e023dcbe..0000000000
--- a/rts/adjustor/NativeSparc.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -----------------------------------------------------------------------------
- * SPARC architecture adjustor thunk logic.
- * ---------------------------------------------------------------------------*/
-
-#include "rts/PosixSource.h"
-#include "Rts.h"
-
-#include "RtsUtils.h"
-#include "StablePtr.h"
-
-void*
-createAdjustor(int cconv, StgStablePtr hptr,
- StgFunPtr wptr,
- char *typeString STG_UNUSED
- )
-{
- switch (cconv)
- {
- case 1: /* _ccall */
- /* Magic constant computed by inspecting the code length of the following
- assembly language snippet (offset and machine code prefixed):
-
- <00>: 9C23A008 sub %sp, 8, %sp ! make room for %o4/%o5 in caller's frame
- <04>: DA23A060 st %o5, [%sp + 96] ! shift registers by 2 positions
- <08>: D823A05C st %o4, [%sp + 92]
- <0C>: 9A10000B mov %o3, %o5
- <10>: 9810000A mov %o2, %o4
- <14>: 96100009 mov %o1, %o3
- <18>: 94100008 mov %o0, %o2
- <1C>: 13000000 sethi %hi(wptr), %o1 ! load up wptr (1 of 2)
- <20>: 11000000 sethi %hi(hptr), %o0 ! load up hptr (1 of 2)
- <24>: 81C26000 jmp %o1 + %lo(wptr) ! jump to wptr (load 2 of 2)
- <28>: 90122000 or %o0, %lo(hptr), %o0 ! load up hptr (2 of 2, delay slot)
- <2C> 00000000 ! place for getting hptr back easily
-
- ccall'ing on SPARC is easy, because we are quite lucky to push a
- multiple of 8 bytes (1 word hptr + 1 word dummy arg) in front of the
- existing arguments (note that %sp must stay double-word aligned at
- all times, see ABI spec at http://www.sparc.org/standards/psABI3rd.pdf).
- To do this, we extend the *caller's* stack frame by 2 words and shift
- the output registers used for argument passing (%o0 - %o5, we are a *leaf*
- procedure because of the tail-jump) by 2 positions. This makes room in
- %o0 and %o1 for the additional arguments, namely hptr and a dummy (used
- for destination addr of jump on SPARC, return address on x86, ...). This
- shouldn't cause any problems for a C-like caller: alloca is implemented
- similarly, and local variables should be accessed via %fp, not %sp. In a
- nutshell: This should work! (Famous last words! :-)
- */
- {
- ExecPage *page = allocateExecPage();
- unsigned long *const adj_code = (unsigned long *) page;
-
- adj_code[ 0] = 0x9C23A008UL; /* sub %sp, 8, %sp */
- adj_code[ 1] = 0xDA23A060UL; /* st %o5, [%sp + 96] */
- adj_code[ 2] = 0xD823A05CUL; /* st %o4, [%sp + 92] */
- adj_code[ 3] = 0x9A10000BUL; /* mov %o3, %o5 */
- adj_code[ 4] = 0x9810000AUL; /* mov %o2, %o4 */
- adj_code[ 5] = 0x96100009UL; /* mov %o1, %o3 */
- adj_code[ 6] = 0x94100008UL; /* mov %o0, %o2 */
- adj_code[ 7] = 0x13000000UL; /* sethi %hi(wptr), %o1 */
- adj_code[ 7] |= ((unsigned long)wptr) >> 10;
- adj_code[ 8] = 0x11000000UL; /* sethi %hi(hptr), %o0 */
- adj_code[ 8] |= ((unsigned long)hptr) >> 10;
- adj_code[ 9] = 0x81C26000UL; /* jmp %o1 + %lo(wptr) */
- adj_code[ 9] |= ((unsigned long)wptr) & 0x000003FFUL;
- adj_code[10] = 0x90122000UL; /* or %o0, %lo(hptr), %o0 */
- adj_code[10] |= ((unsigned long)hptr) & 0x000003FFUL;
-
- adj_code[11] = (unsigned long)hptr;
-
- freezeExecPage(page);
-
- /* flush cache */
- asm("flush %0" : : "r" (adj_code ));
- asm("flush %0" : : "r" (adj_code + 2));
- asm("flush %0" : : "r" (adj_code + 4));
- asm("flush %0" : : "r" (adj_code + 6));
- asm("flush %0" : : "r" (adj_code + 10));
-
- /* max. 5 instructions latency, and we need at >= 1 for returning */
- asm("nop");
- asm("nop");
- asm("nop");
- asm("nop");
-
- return page;
- }
-
- default:
- barf("createAdjustor: Unsupported calling convention");
- }
-}
-
-void
-freeHaskellFunctionPtr(void* ptr)
-{
- if ( *(unsigned long*)ptr != 0x9C23A008UL ) {
- errorBelch("freeHaskellFunctionPtr: not for me, guv! %p\n", ptr);
- return;
- }
-
- /* Free the stable pointer first..*/
- freeStablePtr(*((StgStablePtr*)((unsigned long*)ptr + 11)));
-
- freeExecPage(ptr);
-}
diff --git a/rts/include/stg/SMP.h b/rts/include/stg/SMP.h
index 282680c772..8aaf706f59 100644
--- a/rts/include/stg/SMP.h
+++ b/rts/include/stg/SMP.h
@@ -390,9 +390,6 @@ write_barrier(void) {
__asm__ __volatile__ ("lwsync" : : : "memory");
#elif defined(s390x_HOST_ARCH)
__asm__ __volatile__ ("" : : : "memory");
-#elif defined(sparc_HOST_ARCH)
- /* Sparc in TSO mode does not require store/store barriers. */
- __asm__ __volatile__ ("" : : : "memory");
#elif defined(arm_HOST_ARCH) || defined(aarch64_HOST_ARCH)
__asm__ __volatile__ ("dmb st" : : : "memory");
#elif defined(riscv64_HOST_ARCH)
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
index 06afae631d..c5d009639e 100644
--- a/rts/linker/Elf.c
+++ b/rts/linker/Elf.c
@@ -87,9 +87,7 @@
*/
#define X86_64_ELF_NONPIC_HACK (!RtsFlags.MiscFlags.linkerAlwaysPic)
-#if defined(sparc_HOST_ARCH)
-# define ELF_TARGET_SPARC /* Used inside <elf.h> */
-#elif defined(i386_HOST_ARCH)
+#if defined(i386_HOST_ARCH)
# define ELF_TARGET_386 /* Used inside <elf.h> */
#elif defined(x86_64_HOST_ARCH)
# define ELF_TARGET_X64_64
@@ -1463,8 +1461,7 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
return 1;
}
-/* Do ELF relocations for which explicit addends are supplied.
- sparc-solaris relocations appear to be of this form. */
+/* Do ELF relocations for which explicit addends are supplied. */
static int
do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
Elf_Shdr* shdr, int shnum )
@@ -1481,8 +1478,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
#if defined(SHN_XINDEX)
Elf_Word* shndx_table = get_shndx_table((Elf_Ehdr*)ehdrC);
#endif
-#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(powerpc_HOST_ARCH) \
- || defined(x86_64_HOST_ARCH)
+#if defined(DEBUG) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
/* This #if def only serves to avoid unused-var warnings. */
Elf_Addr targ = (Elf_Addr) oc->sections[target_shndx].start;
#endif
@@ -1500,24 +1496,19 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
for (j = 0; j < nent; j++) {
-#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(powerpc_HOST_ARCH) \
- || defined(x86_64_HOST_ARCH)
+#if defined(DEBUG) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
/* This #if def only serves to avoid unused-var warnings. */
Elf_Addr offset = rtab[j].r_offset;
Elf_Addr P = targ + offset;
Elf_Addr A = rtab[j].r_addend;
#endif
-#if defined(sparc_HOST_ARCH) || defined(powerpc_HOST_ARCH) \
- || defined(x86_64_HOST_ARCH)
+#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
Elf_Addr value;
#endif
Elf_Addr info = rtab[j].r_info;
Elf_Addr S;
void* S_tmp;
-# if defined(sparc_HOST_ARCH)
- Elf_Word* pP = (Elf_Word*)P;
- Elf_Word w1, w2;
-# elif defined(powerpc_HOST_ARCH)
+# if defined(powerpc_HOST_ARCH)
Elf_Sword delta;
# endif
@@ -1587,66 +1578,18 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
IF_DEBUG(linker_verbose,debugBelch("`%s' resolves to %p\n", symbol, (void*)S));
}
-#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(powerpc_HOST_ARCH) \
- || defined(x86_64_HOST_ARCH)
+#if defined(DEBUG) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
IF_DEBUG(linker_verbose,debugBelch("Reloc: P = %p S = %p A = %p\n",
(void*)P, (void*)S, (void*)A ));
checkProddableBlock(oc, (void*)P, sizeof(Elf_Word));
#endif
-#if defined(sparc_HOST_ARCH) || defined(powerpc_HOST_ARCH) \
- || defined(x86_64_HOST_ARCH)
+#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
value = S + A;
#endif
switch (ELF_R_TYPE(info)) {
-# if defined(sparc_HOST_ARCH)
- case R_SPARC_WDISP30:
- w1 = *pP & 0xC0000000;
- w2 = (Elf_Word)((value - P) >> 2);
- CHECK((w2 & 0xC0000000) == 0);
- w1 |= w2;
- *pP = w1;
- break;
- case R_SPARC_HI22:
- w1 = *pP & 0xFFC00000;
- w2 = (Elf_Word)(value >> 10);
- CHECK((w2 & 0xFFC00000) == 0);
- w1 |= w2;
- *pP = w1;
- break;
- case R_SPARC_LO10:
- w1 = *pP & ~0x3FF;
- w2 = (Elf_Word)(value & 0x3FF);
- CHECK((w2 & ~0x3FF) == 0);
- w1 |= w2;
- *pP = w1;
- break;
-
- /* According to the Sun documentation:
- R_SPARC_UA32
- This relocation type resembles R_SPARC_32, except it refers to an
- unaligned word. That is, the word to be relocated must be treated
- as four separate bytes with arbitrary alignment, not as a word
- aligned according to the architecture requirements.
- */
- case R_SPARC_UA32:
- w2 = (Elf_Word)value;
-
- // SPARC doesn't do misaligned writes of 32 bit words,
- // so we have to do this one byte-at-a-time.
- char *pPc = (char*)pP;
- pPc[0] = (char) ((Elf_Word)(w2 & 0xff000000) >> 24);
- pPc[1] = (char) ((Elf_Word)(w2 & 0x00ff0000) >> 16);
- pPc[2] = (char) ((Elf_Word)(w2 & 0x0000ff00) >> 8);
- pPc[3] = (char) ((Elf_Word)(w2 & 0x000000ff));
- break;
-
- case R_SPARC_32:
- w2 = (Elf_Word)value;
- *pP = w2;
- break;
-# elif defined(powerpc_HOST_ARCH)
+# if defined(powerpc_HOST_ARCH)
case R_PPC_ADDR16_LO:
*(Elf32_Half*) P = value;
break;
diff --git a/rts/rts.cabal.in b/rts/rts.cabal.in
index e7d5c4a7c7..ec907cd10b 100644
--- a/rts/rts.cabal.in
+++ b/rts/rts.cabal.in
@@ -465,8 +465,6 @@ library
c-sources: adjustor/NativePowerPC.c
if arch(ia64)
c-sources: adjustor/NativeIA64.c
- if arch(sparc)
- c-sources: adjustor/NativeSparc.c
-- Use assembler STG entrypoint on archictures where it is used
if arch(ppc) || arch(ppc64) || arch(s390x) || arch(riscv64)
diff --git a/rts/sm/GCTDecl.h b/rts/sm/GCTDecl.h
index e740392c15..2fbe1894f8 100644
--- a/rts/sm/GCTDecl.h
+++ b/rts/sm/GCTDecl.h
@@ -85,26 +85,6 @@ extern __thread gc_thread* gct;
/* -------------------------------------------------------------------------- */
-/* Next up: On SPARC we can't pin gct to a register. Names like %l1
- are just offsets into the register window, which change on each
- function call.
-
- There are eight global (non-window) registers, but they're used for other
- purposes:
-
- %g0 -- always zero
- %g1 -- volatile over function calls, used by the linker
- %g2-%g3 -- used as scratch regs by the C compiler (caller saves)
- %g4 -- volatile over function calls, used by the linker
- %g5-%g7 -- reserved by the OS
-*/
-#elif defined(sparc_HOST_ARCH)
-extern __thread gc_thread* gct;
-#define SET_GCT(to) gct = (to)
-#define DECLARE_GCT __thread gc_thread* gct;
-
-/* -------------------------------------------------------------------------- */
-
/* Next up: generally, if REG_Base is defined and we're *not* using
i386, then actually declare the needed register. The catch for i386
here is that REG_Base is %ebx, but that is also used for -fPIC, so