2 typedef unsigned long va_list;
5 #define __read(source) \
7 __asm__ __volatile__( \
8 "move\t%0, " #source "\n\t" \
24 static int format_decode(char *fmt
, struct printf_spec
*spec
)
28 for (; *fmt
; ++fmt
) {
36 spec
->type
= FORMAT_TYPE_HEX
;
40 spec
->type
= FORMAT_TYPE_ULONG
;
44 spec
->type
= FORMAT_TYPE_FLOAT
;
48 spec
->type
= FORMAT_TYPE_NONE
;
54 void *memcpy(void *dest
, void *src
, int n
)
60 for (i
= 0; i
< n
; i
++) {
66 char *number(char *buf
, va_list num
)
70 static char digits
[16] = "0123456789abcdef";
71 str
= str
+ sizeof(num
) * 2;
73 for (i
= 0; i
< sizeof(num
) * 2; i
++) {
74 *--str
= digits
[num
& 15];
78 return buf
+ sizeof(num
) * 2;
81 char *__number(char *buf
, va_list num
)
92 for (i
= 0; mm
; mm
= mm
/10, i
++) {
99 *--str
= num
% 10 + 48;
106 va_list modf(va_list args
, va_list *integer
, va_list *num
)
110 va_list E
, DOT
, DOT_V
;
116 for (i
= 0, args
= args
<< 1 >> 1; i
< 52; i
++) {
117 if ((args
>> i
) & 0x1) {
124 if ((args
>> 56 != 0x3f) || (args
>> 52 == 0x3ff)) {
125 E
= (args
>> 52) - 1023;
127 DOT_V
= args
<< (12 + E
) >> (12 + E
) >> i
;
128 *integer
= ((args
<< 12 >> 12) >> (i
+ DOT
)) | (1 << E
);
130 E
= ~((args
>> 52) - 1023) + 1;
131 DOT_V
= args
<< 12 >> 12;
133 dot_v
+= 1.0 / (1 << E
);
135 for (i
= 1; i
<= 16; i
++) {
136 if ((DOT_V
>> (52 - i
)) & 0x1) {
137 dot_v
+= 1.0 / (1 << E
+ i
);
141 for (i
= 1, E
= 0; i
<= ACC
; i
++) {
143 if (!(va_list)dot_v
) {
154 for (i
= 1; i
<= 16; i
++) {
155 if ((DOT_V
>> (DOT
- i
)) & 0x1) {
156 dot_v
+= 1.0 / (1 << i
);
160 for (i
= 1, E
= 0; i
<= ACC
; i
++) {
162 if (!(va_list)dot_v
) {
171 for (i
= 1; i
<= DOT
; i
++) {
172 if ((DOT_V
>> (DOT
- i
)) & 0x1) {
173 dot_v
+= 1.0 / (1 << i
);
177 for (i
= 1; i
<= ACC
; i
++) {
187 int vsnprintf(char *buf
, int size
, char *fmt
, va_list args
)
190 struct printf_spec spec
= {0};
196 int read
= format_decode(fmt
, &spec
);
201 case FORMAT_TYPE_NONE
: {
202 memcpy(str
, old_fmt
, read
);
206 case FORMAT_TYPE_HEX
: {
207 memcpy(str
, old_fmt
, read
);
208 str
= number(str
+ read
, args
);
217 case FORMAT_TYPE_ULONG
: {
218 memcpy(str
, old_fmt
, read
- 2);
219 str
= __number(str
+ read
- 2, args
);
222 case FORMAT_TYPE_FLOAT
: {
223 va_list integer
, dot_v
, num
;
224 dot_v
= modf(args
, &integer
, &num
);
225 memcpy(str
, old_fmt
, read
- 2);
227 if ((args
>> 63 & 0x1)) {
230 str
= __number(str
, integer
);
236 str
= __number(str
, dot_v
);
247 static void serial_out(char *str
)
250 *(char *)0xffffffffb80003f8 = *str
++;
254 int vprintf(char *fmt
, va_list args
)
257 static char printf_buf
[512];
258 printed_len
= vsnprintf(printf_buf
, sizeof(printf_buf
), fmt
, args
);
259 serial_out(printf_buf
);
263 int printf(char *fmt
, ...)
265 return vprintf(fmt
, __read($
5));