HWA
Bare metal programming with style
hwa_path.h
Go to the documentation of this file.
1 
2 /* This file is part of the HWA project.
3  * Copyright (c) 2020 Christophe Duparquet.
4  * All rights reserved. Read LICENSE.TXT for details.
5  */
6 
23 #define HW_XOR(o,r) _HW_XOR1(r,hw_##o##_##r,o,hw_##o)
24 #define _HW_XOR1(...) _HW_XOR2(__VA_ARGS__)
25 #define _HW_XOR2(r,rc,ra,rwm,rfm,o,c,a) HW_OXR(rc,r,ra,rwm,rfm,c,o,a)
26 
27 
37 /* HW_OXR(rc,,r,rbn,rbp,c,o,a) */
38 #define HW_OXR(...) _HW_OXR2(__VA_ARGS__)
39 #define _HW_OXR2(rc,...) _HW_OXR##rc(__VA_ARGS__)
40 
41 #define _HW_OXR_r8(r,ra,rwm,rfm,c,o,a) _m11,(o,r),(o,r,_r8,a+ra,rwm,rfm,8,0)
42 #define _HW_OXR_r16(r,ra,rwm,rfm,c,o,a) _m11,(o,r),(o,r,_r16,a+ra,rwm,rfm,16,0)
43 #define _HW_OXR_r32(r,ra,rwm,rfm,c,o,a) _m11,(o,r),(o,r,_r32,a+ra,rwm,rfm,32,0)
44 
45 #define _HW_OXR_ob1(s,r,bn,bp,c,o,a) _HW_OXR_ob1_01(o,a,r,hw_##o##_##r,bn,bp)
46 #define _HW_OXR_ob1_01(...) _HW_OXR_ob1_02(__VA_ARGS__)
47 #define _HW_OXR_ob1_02(o,a,r,rc,ra,...) _m11,(o,r),(o,r,rc,a+ra,__VA_ARGS__)
48 
49 #define _HW_OXR_cb1(s,r,bn,bp,c,o,a) _HW_OXR_ob1_01(o,a,r,hw_##c##_##r,bn,bp)
50 
51 #define _HW_OXR_xb1(s,xo,xr,bn,bp,...) _HW_OXR_xb1_01(xo,hw_##xo,xr,bn,bp,hw_##xo##_##xr)
52 #define _HW_OXR_xb1_01(...) _HW_OXR_xb1_02(__VA_ARGS__)
53 #define _HW_OXR_xb1_02(o,c,a,r,bn,bp,...) _HW_B(_HW_OXR_xb1_02_,_hw_isa_reg_##__VA_ARGS__)(o,c,a,r,bn,bp,__VA_ARGS__)
54 #define _HW_OXR_xb1_02_1(o,c,a,r,bn,bp,rc,ra,wm,fm) _m11,(o,r),(o,r,rc,a+ra,wm,fm,bn,bp)
55 #define _HW_OXR_xb1_02_0(o,c,a,r,bn,bp,...) _HW_OXR_xb1_03(o,a,r,bn,bp,hw_##c##_##r)
56 #define _HW_OXR_xb1_03(...) _HW_OXR_xb1_04(__VA_ARGS__)
57 #define _HW_OXR_xb1_04(o,a,r,bn,bp,rc,ra,wm,fm) _m11,(o,r),(o,r,rc,a+ra,wm,fm,bn,bp)
58 
59 #define _HW_OXR_ob2(r,r1,bn1,bp1,vp1,r2,bn2,bp2,vp2,c,o,a) \
60  _HW_OXR_ob2_01(o,r,a,r1,hw_##o##_##r1,bn1,bp1,vp1,r2,hw_##o##_##r2,bn2,bp2,vp2)
61 #define _HW_OXR_ob2_01(...) _HW_OXR_ob2_02(__VA_ARGS__)
62 #define _HW_OXR_ob2_02(o,r,a,r1,rc1,ra1,wm1,fm1,bn1,bp1,vp1,r2,rc2,ra2,wm2,fm2,bn2,bp2,vp2) \
63  _m22,(o,r),(o,r1,rc1,a+ra1,wm1,fm1,bn1,bp1,vp1,r2,rc2,a+ra2,wm2,fm2,bn2,bp2,vp2)
64 
65 #define _HW_OXR_cb2(r,r1,bn1,bp1,vp1,r2,bn2,bp2,vp2,c,o,a) \
66  _HW_OXR_ob2_01(o,r,a,r1,hw_##c##_##r1,bn1,bp1,vp1,r2,hw_##c##_##r2,bn2,bp2,vp2)
67 
68 // Assume r1 == r2
69 #define _HW_OXR_xb2(s,xo,r1,bn1,bp1,vp1,r2,bn2,bp2,vp2,c,o,a) \
70  _HW_OXR_xb2_01(o,a,r1,hw_##xo##_##r1,bn1,bp1,vp1,bn2,bp2,vp2)
71 #define _HW_OXR_xb2_01(...) _HW_OXR_xb2_02(__VA_ARGS__)
72 #define _HW_OXR_xb2_02(o,a,r,rc,ra,wm,fm,bn1,bp1,vp1,bn2,bp2,vp2) \
73  _m12,(o,r),(o,r,rc,a+ra,wm,fm,bn1,bp1,vp1,bn2,bp2,vp2)
74 
75 
76 
84 #define HW_XO(o) _HW_XO01(o,hw_##o)
85 #define _HW_XO01(...) _HW_XO02(__VA_ARGS__)
86 #define _HW_XO02(o,...) _HW_B(_HW_XO02,hw_class_##__VA_ARGS__)(o,__VA_ARGS__)
87 #define _HW_XO021(o,c,...) c,o,(__VA_ARGS__)
88 #define _HW_XO020(o,...) _HW_B(_HW_XO020,o)(o)
89 #define _HW_XO0200(o) ,o,HW_EM_O(o) /* o is not the name of an object */
90 #define _HW_XO0201(o) ,o,HW_EM_OM(o) /* object name missing */
91 
92 
101 #define HW_CODR(c,o,...) _HW_B(_HW_CODR_,_hw_par o)(c,o,__VA_ARGS__)
102 #define _HW_CODR_1(c,o,d,r) _HW_CODR2(c,o,d,r,hw_##c##_##r) // Can not compute o_r since o is ()
103 #define _HW_CODR_0(c,o,d,r) _HW_B(_HW_CODR0_,_hw_par r)(c,o,d,r)
104 #define _HW_CODR0_1(c,o,d,r) _HW_CODR6(c,o,d,r,hw_##c##_) // Can not compute o_r since r is ()
105 #define _HW_CODR0_0(c,o,d,r) _HW_CODR0(c,o,d,r,hw_##o##_##r)
106 #define _HW_CODR0(...) _HW_CODR1(__VA_ARGS__)
107 #define _HW_CODR1(c,o,d,r,...) _HW_B(_HW_CODR1_,hw_class_##__VA_ARGS__)(c,o,d,r,__VA_ARGS__)
108 /*
109  * hw_o_r is a definition.
110  */
111 #define _HW_CODR1_1(c,o,d,r,...) _HW_B(_HW_CODR10_,_hw_isa_reg_##__VA_ARGS__)(c,o,d,r,__VA_ARGS__)
112 /*
113  * hw_o_r is not a register. Return the definition.
114  */
115 #define _HW_CODR10_0(c,o,d,r,x,...) x,o##_##r,(__VA_ARGS__)
116 /* #define _HW_CODR10_0(c,o,d,r,x,...) x,(o,r),(__VA_ARGS__) */
117 /*
118  * hw_o_r is a register. Return the memory definition.
119  */
120 #define _HW_CODR10_1(c,o,d,r,cr,...) HW_OXR(cr,r,__VA_ARGS__,c,o,HW_RP d)
121 /*
122  * x is a not a class, is it the name of an object?
123  */
124 #define _HW_CODR1_0(c,o,d,r,x) _HW_CODR10(c,o,d,r,HW_XO(x),)
125 #define _HW_CODR10(...) _HW_CODR11(__VA_ARGS__)
126 #define _HW_CODR11(c,o,d,r,x,...) _HW_B(_HW_CODR11_,hw_class_##x)(c,o,d,r,x,__VA_ARGS__)
127 /*
128  * hw_o_r is the name of an object. Return its definition.
129  */
130 #define _HW_CODR11_1(c,o,d,r,oc,oo,od,...) oc,oo,od
131 /*
132  * hw_o_r is not the name of an object. Try hw_c_r.
133  */
134 #define _HW_CODR11_0(c,o,d,r,...) _HW_CODR2(c,o,d,r,hw_##c##_##r)
135 #define _HW_CODR2(...) _HW_CODR3(__VA_ARGS__)
136 #define _HW_CODR3(c,o,d,r,...) _HW_B(_HW_CODR3_,__VA_ARGS__)(c,o,d,r,__VA_ARGS__)
137 /*
138  * hw_c_r is void -> delegate to the provided function
139  */
140 /* #define _HW_CODR3_1(c,o,d,r,z,f) _HW_CODR4(f,o,HW_RP d) */
141 /* #define _HW_CODR4(f,...) _HW_CODR5(f(__VA_ARGS__)) */
142 /* #define _HW_CODR5(...) __VA_ARGS__ */
143 
144 #define _HW_CODR3_1(c,o,d,r,z,...) _HW_CODR4(__VA_ARGS__,o,HW_RP d)
145 #define _HW_CODR4(f,...) _HW_CODR5(f(__VA_ARGS__))
146 #define _HW_CODR5(...) __VA_ARGS__
147 
148 /*
149  * hw_c_r is not void. FIXME: remove this when its known that it will never be used.
150  */
151 #define _HW_CODR3_0(c,o,d,r,...) _HW_B(_HW_CODR4_,_hw_par __VA_ARGS__)(c,o,d,r,__VA_ARGS__)
152 #define _HW_CODR4_1(c,o,d,r,...) ,(o,r),internal error: expanding () is not implemented [_HW_CODR4_1]
153 /*
154  * hw_c_r is a word.
155  */
156 //#define _HW_CODR4_0(c,o,d,r,...) _HW_B(_HW_CODR5_,_hw_isa_reg_##__VA_ARGS__)(c,o,d,r,__VA_ARGS__)
157 #define _HW_CODR4_0(c,o,d,r,...) _HW_B(_HW_CODR40,hw_class_##__VA_ARGS__)(c,o,d,r,__VA_ARGS__)
158 /*
159  * hw_c_r is an object
160  */
161 #define _HW_CODR401(c,o,d,r,...) _HW_B(_HW_CODR5_,_hw_isa_reg_##__VA_ARGS__)(c,o,d,r,__VA_ARGS__)
162 /*
163  * hw_c_r is a register
164  * Convert the register definition to a memory definition.
165  */
166 #define _HW_CODR5_1(c,o,d,r,cr,...) HW_OXR(cr,r,__VA_ARGS__,c,o,HW_RP d)
167 /*
168  * hw_c_r is not a register
169  * Return the definition
170  */
171 #define _HW_CODR5_0(c,o,d,r,rc,...) rc,(o,r),(__VA_ARGS__)
172 /*
173  * hw_c_r is not an object, try a function hw_c_
174  */
175 #define _HW_CODR400(c,o,d,r,...) _HW_CODR6(c,o,d,r,hw_##c##_)
176 #define _HW_CODR6(...) _HW_CODR7(__VA_ARGS__)
177 #define _HW_CODR7(c,o,d,r,...) _HW_B(_HW_CODR7_,__VA_ARGS__)(c,o,d,r,__VA_ARGS__)
178 /*
179  * hw_c_ is a function that would provide class relatives
180  */
181 #define _HW_CODR7_1(c,o,d,r,z,f) _HW_CODR8(f,o,r,HW_RP d)
182 #define _HW_CODR8(f,...) _HW_CODR9(f(__VA_ARGS__))
183 #define _HW_CODR9(...) __VA_ARGS__
184 
185 #define _HW_CODR7_0(c,o,d,r,...) ,o,HW_EM_OO(o,r)
186 
187 
193 #define HW_XS(x,...) _HW_B(_HW_XS1_,_hw_par x)(x,__VA_ARGS__)
194 #define _HW_XS1_1(...) _HW_XS1_2( HW_RP __VA_ARGS__ ) // Remove parentheses
195 #define _HW_XS1_2(...) _HW_XS1_3(__VA_ARGS__ )
196 #define _HW_XS1_3(x,...) _HW_B(_HW_XS2_,_hw_par x)(x,__VA_ARGS__)
197 #define _HW_XS2_1(x,...) ,o,two many parentheses in path before (__VA_ARGS__) [HW_XS2_1],__VA_ARGS__
198 #define _HW_XS2_0(x,...) HW_B(_HW_XS3_,hw_class_##x)(x,__VA_ARGS__)
199 
200 #define _HW_XS1_0(x,...) HW_B(_HW_XS3_,hw_class_##x)(x,__VA_ARGS__)
201 #define _HW_XS3_0(x,...) _HW_XS3_1( HW_XO(x), __VA_ARGS__ ) // Element 1 is a word, process it
202 #define _HW_XS3_1(...) __VA_ARGS__
203 
204 
220 #define HW_X(...) _HW_X0(__VA_ARGS__,,,,) // Ensure at least 5 arguments
221 
222 #define _HW_X0(x,...) _HW_B(_HW_X0_,_hw_par x)(x,__VA_ARGS__)
223 #define _HW_X0_1(...) _HW_X0_2( HW_RP __VA_ARGS__ ) // Remove parentheses
224 #define _HW_X0_2(...) _HW_X0_0(__VA_ARGS__ )
225 
226 #define _HW_X0_0(...) _HW_X0_3( HW_XS(__VA_ARGS__) ) // Element 1: starter
227 #define _HW_X0_3(...) _HW_X0_4( __VA_ARGS__)
228 #define _HW_X0_4(x,...) _HW_B(_HW_X1_,x)(x,__VA_ARGS__)
229 #define _HW_X1_1(c,o,d,...) _HW_X9(c,o,d)
230 
231 #define _HW_X1_0(c,o,d,x,...) HW_B(_HW_X2_,x)(c,o,d,x,__VA_ARGS__) // Element 2
232 #define _HW_X2_1(c,o,d,...) _HW_X9(c,o,d)
233 #define _HW_X2_0(c,o,d,r,...) _HW_X2_2( HW_CODR(c,o,d,r), __VA_ARGS__ )
234 #define _HW_X2_2(...) _HW_X3(__VA_ARGS__)
235 
236 #define _HW_X3(c,o,d,x,...) HW_B(_HW_X3_,x)(c,o,d,x,__VA_ARGS__) // Element 3
237 #define _HW_X3_1(c,o,d,...) _HW_X9(c,o,d)
238 #define _HW_X3_0(c,o,d,r,...) _HW_X3_2( HW_CODR(c,o,d,r), __VA_ARGS__ )
239 #define _HW_X3_2(...) _HW_X4(__VA_ARGS__)
240 
241 #define _HW_X4(c,o,d,x,...) HW_B(_HW_X4_,x)(c,o,d,x,__VA_ARGS__) // Element 4
242 #define _HW_X4_1(c,o,d,...) _HW_X9(c,o,d)
243 #define _HW_X4_0(c,o,d,r,...) _HW_X4_2( HW_CODR(c,o,d,r), __VA_ARGS__ )
244 #define _HW_X4_2(...) _HW_X5(__VA_ARGS__)
245 
246 #define _HW_X5(c,o,d,x,...) HW_B(_HW_X5_,x)(c,o,d,x,__VA_ARGS__) // Element 5
247 #define _HW_X5_1(c,o,d,...) _HW_X9(c,o,d)
248 #define _HW_X5_0(c,o,d,r,...) _HW_X5_2( HW_CODR(c,o,d,r), __VA_ARGS__ )
249 #define _HW_X5_2(...) _HW_X6(__VA_ARGS__)
250 
251 #define _HW_X6(c,o,d,x,...) HW_B(_HW_X6_,x)(c,o,d,x,__VA_ARGS__) // End
252 #define _HW_X6_1(c,o,d,...) _HW_X9(c,o,d)
253 #define _HW_X6_0(c,o,d,x,...) ,o,HW_EM(too many elements in path starting from x) [_HW_X6_0:c,o,d,x,__VA_ARGS__]
254 
255 #define _HW_X9(c,o,d) _HW_B(_HW_X9_,_hw_par d)(c,o,d)
256 #define _HW_X9_1(c,o,d) _HW_X9_0(c,o,HW_RP d)
257 #define _HW_X9_0(...) __VA_ARGS__
258 
259 
268 #define HW(...) _HW_1( HW_X(__VA_ARGS__) )
269 #define _HW_1(...) _HW_2(__VA_ARGS__)
270 #define _HW_2(c,o,...) _HW_B(_HW_2,o)(c,o,__VA_ARGS__)
271 #define _HW_20(...) __VA_ARGS__ /* definition */
272 #define _HW_21(c,o,...) c /* function name */
273 
274 
280 #define HW_C3(...) _HW_C3(__VA_ARGS__)
281 #define _HW_C3(c,o,...) c,o,(__VA_ARGS__)