///--------------------------------------------------------------------------
/// General definitions.
+// Some useful variables.
+ .L$_subsec = 0
+
+// Literal pools done the hard way.
+#define _LIT .text .L$_subsec + 1
+#define _ENDLIT .text .L$_subsec
+
// Announcing an external function.
#define FUNC(name) \
.globl F(name); \
#define _ENDFUNC(name) \
.purgem ENDFUNC; \
SIZE_OBJ(name); \
- ENDFUNC_HOOK(name)
+ ENDFUNC_HOOK(name); \
+ .L$_subsec = .L$_subsec + 2; \
+ .text .L$_subsec
///--------------------------------------------------------------------------
/// ELF-specific hacking.
#if CPUFAM_ARM
+// ARM/Thumb mode things. Use ARM by default.
+#define ARM .arm; .L$_pcoff = 8
+#define THUMB .thumb; .L$_pcoff = 4
+ ARM
+
// Set the function hooks.
#define FUNC_PREHOOK(_) .balign 4
#define ENDFUNC_HOOK(name) .ltorg
#define GOTREG r9
// Maybe load GOT address into GOT.
- .macro ldgot got=r9
+ .macro ldgot cond=, got=GOTREG
#if WANT_PIC
- ldr \got, =_GLOBAL_OFFSET_TABLE_ - . - 12
- add \got, pc, \got
+ ldr\cond \got, .L$_ldgot$\@
+.L$_ldgot_pc$\@:
+ add\cond \got, pc, \got
+ _LIT
+ .balign 4
+.L$_ldgot$\@:
+ .word _GLOBAL_OFFSET_TABLE_ - .L$_ldgot_pc$\@ - .L$_pcoff
+ _ENDLIT
#endif
.endm
// Load address of external symbol ADDR into REG, maybe using GOT.
.macro leaext reg, addr, cond=, got=GOTREG
#if WANT_PIC
- ldr \reg, =\addr(GOT)
- ldr \reg, [\got, \reg]
+ ldr\cond \reg, .L$_leaext$\@
+ ldr\cond \reg, [\got, \reg]
+ _LIT
+ .balign 4
+.L$_leaext$\@:
+ .word \addr(GOT)
+ _ENDLIT
+#else
+ ldr\cond \reg, =\addr
+#endif
+ .endm
+
+// Load address of external symbol ADDR into REG directly.
+ .macro leaextq reg, addr, cond=
+#if WANT_PIC
+ ldr\cond \reg, .L$_leaextq$\@
+.L$_leaextq_pc$\@:
+ .if .L$_pcoff == 8
+ ldr\cond \reg, [pc, \reg]
+ .else
+ add\cond \reg, pc
+ ldr\cond \reg, [\reg]
+ .endif
+ _LIT
+ .balign 4
+.L$_leaextq$\@:
+ .word \addr(GOT_PREL) + (. - .L$_leaextq_pc$\@ - .L$_pcoff)
+ _ENDLIT
#else
- ldr \reg, =\addr
+ ldr\cond \reg, =\addr
#endif
.endm