PageRenderTime 44ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/microcode/cmpauxmd/alpha.m4

#
m4 | 414 lines | 159 code | 21 blank | 234 comment | 0 complexity | e51690aed641fd96c80821f669e6db5c MD5 | raw file
Possible License(s): GPL-2.0
  1. ### -*- Midas -*-
  2. ###
  3. ### Copyright (C) 1992 Digital Equipment Corporation (D.E.C.)
  4. ### Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993,
  5. ### 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
  6. ### 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
  7. ### 2014 Massachusetts Institute of Technology
  8. ###
  9. ### This software was developed at the Digital Equipment Corporation
  10. ### Cambridge Research Laboratory. Permission to copy this software, to
  11. ### redistribute it, and to use it for any purpose is granted, subject to
  12. ### the following restrictions and understandings.
  13. ###
  14. ### 1. Any copy made of this software must include this copyright notice
  15. ### in full.
  16. ###
  17. ### 2. Users of this software agree to make their best efforts (a) to
  18. ### return to both the Digital Equipment Corporation Cambridge Research
  19. ### Lab (CRL) and the MIT Scheme project any improvements or extensions
  20. ### that they make, so that these may be included in future releases; and
  21. ### (b) to inform CRL and MIT of noteworthy uses of this software.
  22. ###
  23. ### 3. All materials developed as a consequence of the use of this
  24. ### software shall duly acknowledge such use, in accordance with the usual
  25. ### standards of acknowledging credit in academic research.
  26. ###
  27. ### 4. D.E.C. has made no warrantee or representation that the operation
  28. ### of this software will be error-free, and D.E.C. is under no obligation
  29. ### to provide any services, by way of maintenance, update, or otherwise.
  30. ###
  31. ### 5. In conjunction with products arising from the use of this material,
  32. ### there shall be no use of the name of the Digital Equipment Corporation
  33. ### nor of any adaptation thereof in any advertising, promotional, or
  34. ### sales literature without prior written consent from D.E.C. in each
  35. ### case.
  36. ### Alpha Architecture assembly language part of the compiled
  37. ### code interface. See cmpint.txt, cmpint.c, cmpint-alpha.h, and
  38. ### cmpgc.h for more documentation.
  39. ###
  40. ### NOTE:
  41. ### Assumptions:
  42. ###
  43. ### 1) The C compiler divides registers into three groups:
  44. ### - Linkage registers, used for procedure calls and global
  45. ### references. On Alpha: 26 (return address), 27 (procedure
  46. ### descriptor), 28 (assembler temp), 29 (global pointer),
  47. ### 30 (stack pointer), and 31 (always 0).
  48. ### - super temporaries, not preserved accross procedure calls and
  49. ### always usable. On Alpha: 0-8, 16-21 (argument registers), and
  50. ### 22-25. Values are returned in 0.
  51. ### - preserved registers saved by the callee if they are written.
  52. ### On Alpha: 9-14, 15 (frame base)
  53. ###
  54. ### 2) Arguments, if passed on a stack, are popped by the caller.
  55. ### Thus most "leaf" procedures need not worry about them. On
  56. ### Alpha: The first six arguments are passed in registers and
  57. ### have no space allocated on the stack. Integer scalars are
  58. ### returned in register 0; floating point scalars are returned
  59. ### in fp0; floating point complex numbers are returned in fp0 and
  60. ### fp1; structured values are returned through a pointer passed
  61. ### in the first argument register and the remaining arguments are
  62. ### shifted over by one register.
  63. ###
  64. ### 3) There is a hardware or software maintained stack for
  65. ### control. The procedure calling sequence may leave return
  66. ### addresses in registers, but they must be saved somewhere for
  67. ### nested calls and recursive procedures. On Alpha: Passed in a
  68. ### register, and no slot stack exists. The return link is in 26.
  69. ### The (C) stack pointer is in 30.
  70. ###
  71. ### 4) C procedures return long values in a super temporary
  72. ### register. Alpha: two or more word structures are returned in
  73. ### a location specified by the contents of the first argument
  74. ### register, and all other arguments are shifted over one
  75. ### location (i.e. apparent argument 1 is passed in the register
  76. ### usually used for argument 2, etc.)
  77. ###
  78. ### 5) On Alpha we don't know the floating point register save
  79. ### convention yet.
  80. ###
  81. ### Compiled Scheme code uses the following register convention.
  82. ### Note that scheme_to_interface, the register block, the closure
  83. ### hook, link_to_interface, compiled_entry_type_bits, and
  84. ### closure_free are preserved by C calls, but the others are not,
  85. ### since they change dynamically. trampoline_to_interface can be
  86. ### reached at a fixed offset from scheme_to_interface.
  87. ###
  88. ### Register Usage Information
  89. ### Number .dis C Scheme
  90. ### ====== ==== ======= ======
  91. ### 0 v0 Return Value Return Value
  92. ### 1 t0 caller saves <free, but utility index (not shifted)>
  93. ### 2 t1 caller saves Stack-Pointer
  94. ### 3 t2 caller saves MemTop
  95. ### 4 t3 caller saves Free
  96. ### 5 t4 caller saves Dynamic Link
  97. ### 6 t5 caller saves <free>
  98. ### 7 t6 caller saves <free>
  99. ### 8 t7 caller saves <free>
  100. ### 9 s0 callee saves Regs-Pointer
  101. ### 10 s1 callee saves Scheme-To-Interface
  102. ### 11 s2 callee saves Closure Hook (jump ind. for full addr.)
  103. ### 12 s3 callee saves Link-To-Interface
  104. ### 13 s4 callee saves Compiled-Entry-Type-Bits
  105. ### 14 s5 callee saves Closure-Free
  106. ### 15 fp? frame base <free>
  107. ### 16 a0 argument 1 <free, but for utilities>
  108. ### 17 a1 argument 2 <free, but for utilities>
  109. ### 18 a2 argument 3 <free, but for utilities>
  110. ### 19 a3 argument 4 <free, but for utilities>
  111. ### 20 a4 argument 5 <free, but for utilities>
  112. ### 21 a5 argument 6 <free>
  113. ### 22 t8 caller saves <free>
  114. ### 23 t9 caller saves <free>
  115. ### 24 t10 caller saves <free>
  116. ### 25 t11 caller saves <free>
  117. ### 26 ra return address <free, but used for closure linkage>
  118. ### 27 t12 proc. descript. <free>
  119. ### 28 at? volatile scratch Assembler Temporary (tensioning)
  120. ### 29 gp global pointer <free>
  121. ### 30 sp stack pointer C Stack Pointer (do not use!)
  122. ### 31 zero Z E R O Z E R O
  123. # The following are derived from cmpint-alpha.h, scaled by 8
  124. #define REGBLOCK_FIRST_EXTRA 128
  125. #define REGBLOCK_ADDRESS_OF_STACK_POINTER REGBLOCK_FIRST_EXTRA
  126. #define REGBLOCK_ADDRESS_OF_FREE REGBLOCK_FIRST_EXTRA+8
  127. #define REGBLOCK_ADDRESS_OF_UTILITY_TABLE REGBLOCK_FIRST_EXTRA+16
  128. #define REGBLOCK_ALLOCATE_CLOSURE REGBLOCK_FIRST_EXTRA+24
  129. # The following are derived from const.h, scaled by 8
  130. #define REGBLOCK_MEMTOP 0
  131. #define REGBLOCK_STACKGUARD 8
  132. #define REGBLOCK_VAL 16
  133. #define REGBLOCK_ENV 24
  134. #define REGBLOCK_COMPILER_TEMP 32
  135. #define REGBLOCK_EXPR 40
  136. #define REGBLOCK_RETURN 48
  137. #define REGBLOCK_LEXPR_ACTUALS 56
  138. #define REGBLOCK_PRIMITIVE 64
  139. #define REGBLOCK_CLOSURE_FREE 72
  140. #define REGBLOCK_CLOSURE_SPACE 80
  141. #include "types.h"
  142. #include <machine/pal.h>
  143. .text
  144. .set noat
  145. .set noreorder
  146. .set nomacro
  147. ### A bunch of .aent pseudo-ops were removed because they generate
  148. ### a NOP, and we are counting instructions
  149. # .align 16
  150. # ^ Apparently the assembler does not like that, but will take the following.
  151. # Even though the manual says 1-4 is the valid range.
  152. .align 12
  153. .ent hook_jump_table 0
  154. .globl hook_jump_table
  155. hook_jump_table:
  156. # All entries in this table must be exactly four
  157. # instructions long (see lapgen.scm)
  158. ### .aent scheme_closure_hook
  159. .globl scheme_closure_hook
  160. scheme_closure_hook: # Entry 0, Offset 0
  161. # Compiled code in a closure can be of the form
  162. # JMP $26,($11),0
  163. # <desired address>
  164. # when <desired address> is too far away, and $11
  165. # points here.
  166. ldq $22,0($26)
  167. jmp $28,($22),0
  168. nop
  169. nop
  170. ### .aent asm_allocate_closure
  171. asm_allocate_closure: # Entry 1, Offset 16
  172. # This must preserve ALL Scheme allocatable registers
  173. # $16 has the total number of Scheme objects to allocate
  174. # $17 has pointer to the first entry point, 16 bytes into the
  175. # block we failed to allocate.
  176. # $28 has the return address
  177. # Returns an offset 16 bytes into the allocated space in $17
  178. # It fills the allocated region with
  179. # SUBQ SP,#8,SP//JMP $26,($11),hint
  180. # and then synchronizes the I- and D-caches for this region of
  181. # memory. It also needs to update regnum:closure-free and
  182. # free (i.e. registers $14 and $4)
  183. stq $0,80($sp)
  184. stq $1,88($sp)
  185. ldq $1,REGBLOCK_ADDRESS_OF_FREE($9)
  186. br $31,asm_allocate_continue
  187. asm_allocate_continue:
  188. stq $2,96($sp)
  189. # Register 3 is MemTop
  190. stq $4,0($1) # Store into Free itself
  191. stq $5,104($sp)
  192. stq $6,112($sp)
  193. stq $7,120($sp)
  194. stq $8,128($sp)
  195. # 9 - 15 are callee saves anyway
  196. # 16 and 17 are the argument registers we are passing through
  197. stq $18,136($sp)
  198. stq $19,144($sp)
  199. stq $20,152($sp)
  200. stq $21,160($sp)
  201. stq $22,168($sp)
  202. stq $23,176($sp)
  203. stq $24,184($sp)
  204. stq $25,192($sp)
  205. stq $26,200($sp)
  206. stq $27,208($sp)
  207. stq $28,216($sp)
  208. stq $29,224($sp)
  209. # 30 is the stack pointer itself, 31 is ZERO
  210. ldq $27,REGBLOCK_ALLOCATE_CLOSURE($9)
  211. jsr $26,($27),allocate_closure
  212. ldq $29,REGBLOCK_ADDRESS_OF_FREE($9)
  213. bis $0,$0,$17 # Return the value in $17
  214. ldq $0,80($sp)
  215. ldq $1,88($sp)
  216. ldq $2,96($sp)
  217. ldq $3,REGBLOCK_MEMTOP($9)
  218. ldq $4,0($29) # Retrieve from Free itself
  219. ldq $5,104($sp)
  220. ldq $6,112($sp)
  221. ldq $7,120($sp)
  222. ldq $8,128($sp)
  223. ldq $14,REGBLOCK_CLOSURE_FREE($9)
  224. ldq $18,136($sp)
  225. ldq $19,144($sp)
  226. ldq $20,152($sp)
  227. ldq $21,160($sp)
  228. ldq $22,168($sp)
  229. ldq $23,176($sp)
  230. ldq $24,184($sp)
  231. ldq $25,192($sp)
  232. ldq $26,200($sp)
  233. ldq $27,208($sp)
  234. ldq $28,216($sp)
  235. ldq $29,224($sp)
  236. ret $28,($28),1
  237. .end hook_jump_table
  238. .align 4
  239. .globl Flush_I_Cache
  240. .ent Flush_I_Cache 0
  241. Flush_I_Cache:
  242. call_pal PAL_imb
  243. ret $28,($26),1
  244. .end Flush_I_Cache
  245. # Argument (in $a0) is a compiled Scheme entry point
  246. # but save C registers first
  247. #
  248. # Frame layout:
  249. #define FRAME_SIZE 232
  250. # ....................
  251. # FS . . <-- Old SP (not our property)
  252. # ....................
  253. #FS-8 . Register save .
  254. # . area used by .
  255. # 80 . Allocate_Closure .
  256. # ....................
  257. # 72 . Return str. high .
  258. # ....................
  259. # 64 . Return str. low .
  260. # ....................
  261. # 56 . Caller's $9 (S0) .
  262. # ....................
  263. # 48 . Caller's $10 (S1).
  264. # ....................
  265. # 40 . Caller's $11 (S2).
  266. # ....................
  267. # 32 . Caller's $12 (S3).
  268. # ....................
  269. # 24 . Caller's $13 (S4).
  270. # ....................
  271. # 16 . Caller's $14 (S5).
  272. # ....................
  273. # 8 . Caller's $15 (FP).
  274. # ....................
  275. # 0 . Our return addr. . <-- New SP
  276. # ....................
  277. # IMPORTANT: If the following sequence is changed,
  278. # link_to_interface must remain aligned!
  279. .align 4
  280. .globl C_to_interface
  281. .ent C_to_interface 1
  282. C_to_interface:
  283. .set macro
  284. ldgp $gp,0($27) # Offset 0, 4
  285. # which expands into (low and high from linker):
  286. # ldah $gp,high($t12)
  287. # lda $gp,low($gp)
  288. .set nomacro
  289. lda $sp,-FRAME_SIZE($sp)
  290. # Offset 8: Allocate frame
  291. stq $9,56($sp) # Offset 12
  292. stq $10,48($sp) # Offset 16
  293. stq $11,40($sp) # Offset 20
  294. stq $12,32($sp) # Offset 24
  295. stq $13,24($sp) # Offset 28
  296. stq $14,16($sp) # Offset 32
  297. stq $15,8($sp) # Offset 36
  298. stq $26,0($sp) # Offset 40
  299. .mask 0x0400fe00, -FRAME_SIZE
  300. .frame $sp,FRAME_SIZE,$26
  301. br $12,setup_registers_continue
  302. # Offset 44
  303. #define LINK_TO_SCHEME 16
  304. # IMPORTANT: The distance between link_to_interface
  305. # and scheme_to_interface is fixed at LINK_TO_SCHEME bytes!
  306. ### .aent link_to_interface
  307. link_to_interface: # Offset 48, SHOULD BE octabyte aligned
  308. # $1 has utility index
  309. # $17 (arg 1) has return address from JMP that got you here
  310. # $18 etc. have other utility arguments if needed
  311. lda $17,4($17) # Skip over format word ...
  312. br $28,scheme_to_interface
  313. nop
  314. nop
  315. .align 4
  316. ### .aent scheme_to_interface
  317. .globl scheme_to_interface
  318. scheme_to_interface:
  319. # $1 has utility index (not shifted)
  320. # $17 (etc.) have utility arguments as needed
  321. ldq $24,REGBLOCK_ADDRESS_OF_UTILITY_TABLE($9) # 0
  322. stq $0,REGBLOCK_VAL($9) # 4
  323. ldq $22,REGBLOCK_ADDRESS_OF_STACK_POINTER($9) # 8
  324. ldq $23,REGBLOCK_ADDRESS_OF_FREE($9) # 12
  325. stq $14,REGBLOCK_CLOSURE_FREE($9)
  326. s8addq $1,$24,$24 # Address of entry in table # 16
  327. stq $2,0($22) # Save sp_register # 20
  328. ldq $27,0($24) # Destination address # 24
  329. lda $16,64($sp) # Return structure value here # 28
  330. stq $4,0($23) # Save Free # 32
  331. jsr $26,($27),comutil_operator_arity_trap
  332. ldq $22,64($sp) # Get next procedure address # 40
  333. ldq $16,72($sp) # Value to pass to next procedure # 44
  334. jmp $28,($22),interface_to_scheme # 48
  335. # Argument (in $a0) is a compiled Scheme entry point. Reload
  336. # the Scheme registers and go to work...any registers not reloaded
  337. # here must be callee saves by C.
  338. .align 4
  339. ### .aent interface_to_scheme
  340. .globl interface_to_scheme
  341. interface_to_scheme:
  342. ldq $0,REGBLOCK_VAL($9) # 64
  343. # Register 1 isn't used
  344. ldq $2,REGBLOCK_ADDRESS_OF_STACK_POINTER($9)
  345. ldq $3,REGBLOCK_MEMTOP($9)
  346. ldq $4,REGBLOCK_ADDRESS_OF_FREE($9)
  347. ldq $2,0($2)
  348. ldq $4,0($4)
  349. zap $0,0x80,$5 # Initialize dynamic link register
  350. .aent off_to_scheme_code
  351. .globl off_to_scheme_code
  352. off_to_scheme_code:
  353. jmp $28,($16),0 # Off to compiled code ...
  354. .align 4
  355. setup_registers_continue:
  356. .set at
  357. .set macro
  358. lda $9,Registers
  359. # lda $10,scheme_to_interface-link_to_interface($12)
  360. # ^ The assembler cannot handle the instruction above.
  361. # The offset is computed by counting the distance between
  362. # both labels.
  363. lda $10,LINK_TO_SCHEME($12)
  364. # lda $11,scheme_closure_hook-link_to_interface($12)
  365. # ^ The assembler cannot handle the instruction above.
  366. # use a more expensive 2-instruction sequence.
  367. lda $11,scheme_closure_hook
  368. .set nomacro
  369. .set noat
  370. # Register 12 already initialized
  371. bis $31,TC_COMPILED_ENTRY,$13
  372. sll $13,56,$13 # Shift to most significant byte
  373. ldq $14,REGBLOCK_CLOSURE_FREE($9)
  374. br $28,interface_to_scheme
  375. .align 4
  376. .aent interface_to_C
  377. .globl interface_to_C
  378. interface_to_C:
  379. # Argument 1 (in $16) is the returned value
  380. bis $16,$16,$0 # Real return value register
  381. ldq $26,0($sp) # Return address
  382. ldq $9,56($sp)
  383. ldq $10,48($sp)
  384. ldq $11,40($sp)
  385. ldq $12,32($sp)
  386. ldq $13,24($sp)
  387. ldq $14,16($sp)
  388. ldq $15,8($sp)
  389. lda $sp,FRAME_SIZE($sp)
  390. ret $28,($26), 1
  391. .end C_to_interface