ARM stuff.
parent
dc8be2905e
commit
4c9acdf153
@ -0,0 +1,98 @@
|
||||
#define DTABLE_OFFSET 32
|
||||
#define SMALLOBJ_MASK 1
|
||||
#define SHIFT_OFFSET 4
|
||||
#define DATA_OFFSET 12
|
||||
#define SLOT_OFFSET 16
|
||||
.syntax unified
|
||||
|
||||
// Macro for testing: logs a register value to standard error
|
||||
.macro LOG reg
|
||||
push {r0-r3, ip,lr}
|
||||
mov r0, \reg
|
||||
bl logInt(PLT)
|
||||
pop {r0-r3, ip,lr}
|
||||
.endm
|
||||
|
||||
.macro MSGSEND receiver, sel
|
||||
teq \receiver, 0
|
||||
beq 4f // Skip everything if the receiver is nil
|
||||
push {r4-r6} // We're going to use these three as
|
||||
// scratch registers, so save them now
|
||||
tst \receiver, SMALLOBJ_MASK // Sets Z if this is not a small int
|
||||
|
||||
|
||||
ldrne r4, LSmallIntClass // Small Int class -> r4 if this is a small int
|
||||
ldrne r4, [r4]
|
||||
|
||||
ldreq r4, [\receiver] // Load class to r4 if not a small int
|
||||
|
||||
ldr r4, [r4, #DTABLE_OFFSET] // Dtable -> r4
|
||||
|
||||
ldr r5, LUninstalledDtable // &uninstalled_dtable -> r5
|
||||
ldr r5, [r5]
|
||||
|
||||
teq r4, r5 // If dtable == &uninstalled_dtable
|
||||
beq 5f // Do a slow lookup
|
||||
|
||||
ldr r5, [\sel] // selector->index -> r5
|
||||
|
||||
ldr r6, [r4, #SHIFT_OFFSET] // dtable->shift -> r6
|
||||
ldr r4, [r4, #DATA_OFFSET] // dtable->data -> r4
|
||||
|
||||
teq r6, #8 // If this is a small dtable, jump to the small dtable handlers
|
||||
beq 1f
|
||||
teq r6, #0
|
||||
beq 2f
|
||||
|
||||
and r6, r5, #0xff0000
|
||||
ldr r4, [r4, r6, asr#14]
|
||||
1: // dtable16
|
||||
and r6, r5, #0xff00
|
||||
ldr r4, [r4, r6, asr#6]
|
||||
2: // dtable8
|
||||
and r6, r5, #0xff
|
||||
ldr ip, [r4, r6, asl#2]
|
||||
|
||||
teq ip, #0 // If the slot is nil
|
||||
beq 5f // Go to the slow path and do the forwarding stuff
|
||||
|
||||
ldr ip, [ip, #SLOT_OFFSET] // Load the method from the slot
|
||||
|
||||
3:
|
||||
pop {r4-r6} // Restore the saved callee-save registers
|
||||
mov pc, ip
|
||||
|
||||
4: // Nil receiver
|
||||
mov r0, 0
|
||||
mov r1, 0
|
||||
mov pc, lr
|
||||
5: // Slow lookup
|
||||
push {r0-r3, lr} // Save anything that will be clobbered by the call
|
||||
|
||||
push {\receiver} // &self, _cmd in arguments
|
||||
mov r0, sp
|
||||
mov r1, \sel
|
||||
bl slowMsgLookup(PLT)
|
||||
mov ip, r0 // IMP -> ip
|
||||
|
||||
pop {r5} // restore (modified) self to r5
|
||||
pop {r0-r3, lr} // Load clobbered registers
|
||||
mov \receiver, r5
|
||||
b 3b
|
||||
.endm
|
||||
|
||||
.globl objc_msgSend
|
||||
.type objc_msgSend, %function
|
||||
objc_msgSend:
|
||||
MSGSEND r0, r1
|
||||
.globl objc_msgSend_sret
|
||||
.type objc_msgSend_sret, %function
|
||||
objc_msgSend_sret:
|
||||
MSGSEND r1, r2
|
||||
|
||||
LSmallIntClass:
|
||||
.long SmallObjectClasses
|
||||
.align 2
|
||||
LUninstalledDtable:
|
||||
.long uninstalled_dtable
|
||||
.align 2
|
||||
Loading…
Reference in New Issue