|
|
1.1 root 1: /* ---------------------------------------- */
2: /* VARARGS for MIPS/GNU CC */
3: /* */
4: /* */
5: /* */
6: /* */
7: /* ---------------------------------------- */
8:
9: /* WARNING: THIS depends heavily on in register parameter
10: passing conventions of the MIPS. This is compatible with MIPS
11: programs, including printf; but differs from MIPS
12: implementation. */
13:
14: /* PROLOGUE FOR VARARGS PROGRAMS:
15:
16: ;;;; META COMMENTS
17: .align 0
18: ;;;; Purpose: identify varargs pgm
19: ;;;; to codegen. I'd rather have a
20: ;;;; Flag in the compiler than this.
21:
22: __vd_alist.0:
23: .ascii "__%%VARARGS\0"
24: .ent zrintf
25: zrintf:
26: #PROLOGUE
27: add $8,$0,$29
28: ;;;; Leave extra space in frame
29: ;;;; to save f12 f14
30: subu $29,112 #temp= 76,saveregs= 32, sfo= -4
31: # .mask 0xc0010000
32: sw $31,4($29)
33: sw $30,8($29)
34: ;;;; Purpose:save stack size on stack
35: ;;;; for easier retrieval
36: addi $9,$0,112 #Varargs suspicion
37: sw $9,-4($8) #Varargs suspicion
38: ;;;; save floating point registers
39: ;;;; into extra stack space (in the
40: ;;;; varargs callee frame, NOT in the
41: ;;;; space saved by caller for register
42: ;;;; argument write back. Thus, we
43: ;;;; can write back both, and let the
44: ;;;; va_arg macro decide what is
45: ;;;; required.
46:
47: s.d $f12,16($29) #Varargs Suspicion
48: s.d $f14,24($29) #Varargs Suspicion
49:
50: sw $16,28($29)
51: # .fmask 0x0
52: add $30,$0,$8
53: #END PROLOGUE
54: ;;;; Write back of r4-r7 due to
55: ;;;; the va_dcl, va_start combination
56:
57: sw $4,0($30) #movsi $4 -> 0($30)
58: sw $5,4($30) #movsi $5 -> 4($30)
59: sw $6,8($30) #movsi $6 -> 8($30)
60: sw $7,12($30) #movsi $7 -> 12($30)
61:
62: */
63:
64: typedef struct
65: { int pnt;
66: char *stack;
67: double *fpregs;
68: } va_list ;
69: /* Used to push R4-R7 to stack */
70: /* and to access argument list on stack */
71: #define va_alist _va_alist, __va_alist,__vb_alist,__vc_alist
72:
73: #define va_dcl int _va_alist, __va_alist,__vb_alist,__vc_alist;
74:
75:
76: #define va_start(list) {\
77: static char __vd_alist[16] = "__%%VARARGS"; /* Identify to codegen */\
78: &__va_alist,&__vb_alist,&__vc_alist, /* write back to stack */\
79: (list).pnt = 0, /* start from first */\
80: (list).stack = (char *) &_va_alist, /* Access parameter list*/\
81: (list).fpregs = (double *)((list).stack -\
82: *(int *)((list).stack -4) + 16), \
83: (list).stack;}
84:
85: #define va_end(list)
86:
87: /* For argument passing convention see */
88: /* both tm.h and Jerry Kane's book */
89:
90: #define va_arg(list,mode) (((mode *)\
91: (((sizeof(mode) > 4) ?\
92: (((list).pnt == 0 )?(((list).pnt = -1),\
93: (list).stack = (char *)\
94: (((int)((list).stack)\
95: + 2*8 - 1) & -8),\
96: (char *)((list).fpregs+1)\
97: )\
98: :((list).pnt == -1) ?((list).pnt = 2,\
99: (list).stack = (char *)\
100: (((int)((list).stack)\
101: + 2*8 - 1) & -8),\
102: (char *)((list).fpregs+2) \
103: )\
104: :(((list).pnt > 0 )?\
105: ((list).pnt =((list).pnt +1),\
106: (list).stack =(char *)\
107: (((int)((list).stack)\
108: + 2*8 - 1) & -8) \
109: ):(char *)abort()))\
110: :((list).pnt = (((list).pnt >=0) ? ((list).pnt +1)\
111: :((list).pnt == -1) ? 2 :3),\
112: (list).stack = (char *)(((int)((list).stack)+ 2*4 - 1) & -4)\
113: )\
114: )))[-1])\
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.