10 int base
, ctindex
, method_ctindex
;
11 std::string functions
;
13 std::string calltable
;
20 vartype( const std::string
&typestr
) {
21 size_t amp
= typestr
.find('&');
22 size_t col
= typestr
.find(':');
23 if( amp
!= std::string::npos
) {
24 if( col
> amp
&& col
!= std::string::npos
)
25 lit_value
= typestr
.substr(amp
+1,col
-amp
+1);
26 else lit_value
= typestr
.substr(amp
+1);
28 if( col
!= std::string::npos
) {
29 if( amp
> col
&& amp
!= std::string::npos
)
30 len
= typestr
.substr(col
+1,amp
-col
+1);
31 else len
= typestr
.substr(col
+1);
34 if( amp
!= std::string::npos
&& amp
< col
) col
= amp
;
35 if( col
== std::string::npos
) col
= typestr
.size();
36 c_type
= typestr
.substr(0,col
);
39 vartype( const vartype
&other
)
40 : c_type(other
.c_type
),
42 lit_value(other
.lit_value
) {
45 vartype
&operator = ( const vartype
&other
) {
46 c_type
= other
.c_type
;
48 lit_value
= other
.lit_value
;
54 std::string lit_value
;
57 std::string
uppercase( const std::string
&toucase
) {
58 std::vector
<char> ucase_work(toucase
.size());
59 for( size_t i
= 0; i
< toucase
.size(); i
++ ) {
60 ucase_work
[i
] = toupper(toucase
[i
]);
62 return std::string(&ucase_work
[0], toucase
.size());
65 std::string
clip_eol( std::string in
, const std::string
&eol_marks
) {
67 for( size_t i
= 0; i
< eol_marks
.size(); i
++ ) {
68 found
= in
.find( eol_marks
[i
] );
69 if( found
!= std::string::npos
)
70 in
= in
.substr( 0, found
);
75 int round_up( int x
, int factor
) {
76 return (x
+ (factor
- 1)) & ~(factor
- 1);
79 void populate_definition( ofw_wrappers
&wrapper
, const std::string
&line
) {
80 std::istringstream
iss(line
);
81 bool make_function
= true, method_call
= false, make_stub
= true, comma
;
82 std::string name
, nametext
, argtype
, rettype
;
83 std::vector
<vartype
> argtypes
;
84 int args
, rets
, i
, local_offset
, total_stack
, userarg_start
= 0;
86 std::ostringstream function
, ct_csource
, le_stub
, of_call
;
88 iss
>> name
>> args
>> rets
;
90 if( !name
.size() ) return;
92 if( (f
= name
.find('!')) != std::string::npos
) {
93 nametext
= name
.substr(f
+1);
94 name
= name
.substr(0,f
);
96 if( name
[0] == '-' ) {
97 name
= name
.substr(1);
98 make_function
= false;
100 if( name
[0] == '+' ) {
101 name
= name
.substr(1);
104 if( name
[0] == '@' ) {
105 name
= name
.substr(1);
107 make_function
= false;
110 if( !nametext
.size() ) nametext
= name
;
112 for( i
= 1; i
< (int)name
.size(); i
++ )
113 if( name
[i
] == '-' ) name
[i
] = '_';
115 if( nametext
== "call-method" )
116 wrapper
.method_ctindex
= wrapper
.ctindex
;
118 for( i
= 0; i
< args
; i
++ ) {
120 argtypes
.push_back(vartype(argtype
));
129 if( !rettype
.size() ) rettype
= "void";
131 local_offset
= (3 + rets
+ args
) * 4;
132 total_stack
= round_up(12 + local_offset
, 16);
134 function
<< "asm_ofw_" << name
<< ":\n"
135 << "\t/* Reserve stack space */\n"
136 << "\tsubi %r1,%r1," << total_stack
<< "\n"
137 << "\t/* Store r8, r9, lr */\n"
138 << "\tstw %r8," << (local_offset
+ 0) << "(%r1)\n"
139 << "\tstw %r9," << (local_offset
+ 4) << "(%r1)\n"
141 << "\tstw %r8," << (local_offset
+ 8) << "(%r1)\n"
142 << "\t/* Get read name */\n"
143 << "\tlis %r8," << name
<< "_ofw_name@ha\n"
144 << "\taddi %r9,%r8," << name
<< "_ofw_name@l\n"
145 << "\tstw %r9,0(%r1)\n"
146 << "\t/* " << args
<< " arguments and " << rets
<< " return */\n"
147 << "\tli %r9," << args
<< "\n"
148 << "\tstw %r9,4(%r1)\n"
149 << "\tli %r9," << rets
<< "\n"
150 << "\tstw %r9,8(%r1)\n";
152 for( int i
= 0; i
< args
; i
++ )
153 function
<< "\tstw %r" << (i
+3) << "," << (4 * (i
+ 3)) << "(%r1)\n";
155 function
<< "\t/* Load up the call address */\n"
156 << "\tlis %r10,ofw_call_addr@ha\n"
157 << "\tlwz %r9,ofw_call_addr@l(%r10)\n"
159 << "\t/* Set argument */\n"
163 << "\tlwz %r3," << (local_offset
- 4) << "(%r1)\n"
164 << "\t/* Restore registers */\n"
165 << "\tlwz %r8," << (local_offset
+ 8) << "(%r1)\n"
167 << "\tlwz %r9," << (local_offset
+ 4) << "(%r1)\n"
168 << "\tlwz %r8," << (local_offset
+ 0) << "(%r1)\n"
169 << "\t/* Return */\n"
170 << "\taddi %r1,%r1," << total_stack
<< "\n"
174 argtypes
.insert(argtypes
.begin(),vartype("int"));
175 argtypes
.insert(argtypes
.begin(),vartype("char*"));
178 le_stub
<< rettype
<< " ofw_" << name
<< "(";
181 for( i
= userarg_start
; i
< args
; i
++ ) {
182 if( !argtypes
[i
].lit_value
.size() ) {
183 if( !comma
) comma
= true; else le_stub
<< ",";
184 le_stub
<< argtypes
[i
].c_type
<< " arg" << i
;
188 of_call
<< le_stub
.str() << ";\n";
191 if( rettype
!= "void" )
192 le_stub
<< "\t" << rettype
<< " ret;\n";
195 le_stub
<< "\tchar arg0["
196 << round_up(nametext
.size()+1,8)
197 << "] = \"" << nametext
<< "\";\n";
200 for( i
= 0; i
< args
; i
++ ) {
201 if( argtypes
[i
].lit_value
.size() ) {
202 le_stub
<< "\t" << argtypes
[i
].c_type
<< " arg" << i
<< " = "
203 << argtypes
[i
].lit_value
<< ";\n";
208 if( rettype
!= "void" ) le_stub
<< "ret = (" << rettype
<< ")";
210 le_stub
<< "ofproxy(" <<
211 (method_call
? (wrapper
.method_ctindex
* 4) : (wrapper
.ctindex
* 4));
213 for( i
= 0; i
< 6; i
++ ) {
214 if( i
< args
) le_stub
<< ",(void *)arg" << i
;
215 else le_stub
<< ",NULL";
220 if( rettype
!= "void" )
221 le_stub
<< "\treturn ret;\n";
225 if( make_function
) wrapper
.functions
+= function
.str();
227 wrapper
.le_stubs
+= le_stub
.str();
228 wrapper
.of_call
+= of_call
.str();
231 wrapper
.names
+= name
+ "_ofw_name:\n\t.asciz \"" + nametext
+ "\"\n";
232 wrapper
.calltable
+= std::string("\t.long asm_ofw_") + name
+ "\n";
237 int main( int argc
, char **argv
) {
240 std::ofstream out
, outcsource
, outcheader
;
242 const char *eol_marks
= "#\r\n";
243 ofw_wrappers wrappers
;
245 wrappers
.base
= 0xe00000;
246 wrappers
.ctindex
= 0;
249 fprintf( stderr
, "%s [interface.ofw] [ofw.s] [le_stub.c] [le_stub.h]\n", argv
[0] );
255 fprintf( stderr
, "can't open %s\n", argv
[1] );
262 fprintf( stderr
, "can't open %s\n", argv
[2] );
267 outcsource
.open( argv
[3] );
269 fprintf( stderr
, "can't open %s\n", argv
[3] );
274 outcheader
.open( argv
[4] );
276 fprintf( stderr
, "can't open %s\n", argv
[4] );
281 while( std::getline( in
, line
) ) {
282 line
= clip_eol( line
, eol_marks
);
283 if( line
.size() ) populate_definition( wrappers
, line
);
286 out
<< "/* AUTOMATICALLY GENERATED BY ofw_interface */\n"
287 << "\t.section .text\n"
289 << "\t.globl _start\n"
290 << "\t.globl ofw_functions\n"
291 << "\t.globl ofw_call_addr\n"
292 << "ofw_call_addr:\n"
294 << "\n/* Function Wrappers */\n\n"
295 << wrappers
.functions
296 << "\n/* Function Names */\n\n"
298 << "\n/* Function Call Table for Freeldr */\n\n"
300 << "ofw_functions:\n"
301 << wrappers
.calltable
304 outcsource
<< "/* AUTOMATICALLY GENERATED BY ofw_interface */\n"
305 << "#include \"of.h\"\n"
306 << wrappers
.le_stubs
;
308 outcheader
<< "/* AUTOMATICALLY GENERATE BY ofw_interface */\n"
309 << "#ifndef _OFW_CALLS_H\n"
310 << "#define _OFW_CALLS_H\n"
312 << "#endif/*_OFW_CALLS_H*/\n";