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));