-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathprintf_light.as
More file actions
647 lines (582 loc) · 27.3 KB
/
printf_light.as
File metadata and controls
647 lines (582 loc) · 27.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
/**************************** printf_light.as ********************************
* Author: Agner Fog
* date created: 2021-05-24
* Last modified: 2023-01-08
* ForwardCom version: 1.12
* Project: ForwardCom library libc_light.li
* Description:
* printf_light, sprintf_light, snprintf_light: Print formatted output.
* These functions are light versions of printf, sprintf, and snprintf
* intended for embedded systems and small CPUs with limited capabilities.
* The following instructions are avoided: mul, div, push, pop, sys_call.
* Output to stdout goes directly to output port 10. It does not wait if
* the output buffer is full.
*
* C declarations:
* int printf_light (const char * format, ... );
* int sprintf_light (char * string, const char * format, ... );
* int snprintf_light (char * string, size_t max_length, const char * format, ... );
*
* printf_light: print to stdout
* sprintf_light: print to string
* snprintf_light: print to string with length limit
* fprintf_light: print to file. not implemented yet
*
* These functions are following the definitions of printf etc. in the C standard.
* All standard features are supported, except the following:
* - cannot print floating point numbers
* - cannot print octal
* - cannot print decimal integers with more than 32 bits
*
* Copyright 2021-2023 GNU General Public License v. 3
* http://www.gnu.org/licenses
*****************************************************************************/
const section read ip
// call table for dispatching format string specifiers
call_table: int8 (specif_space-def)/4 // ' ': print space or minus
int8 0 // !
int8 0 // "
int8 (specif_hash-def)/4 // #: prepend 0x
int8 0 // $
int8 (specif_percent-def)/4 // %: print percent sign
int8 0 // &
int8 0 // '
int8 0 // (
int8 0 // )
int8 (specif_star-def)/4 // *: width specified by parameter
int8 (specif_plus-def)/4 // +: print sign
int8 0 // ,
int8 (specif_minus-def)/4 // -: left justified
int8 0 // .
int8 0 // /
int8 (specif_number-def)/4 // 0
int8 (specif_number-def)/4 // 1
int8 (specif_number-def)/4 // 2
int8 (specif_number-def)/4 // 3
int8 (specif_number-def)/4 // 4
int8 (specif_number-def)/4 // 5
int8 (specif_number-def)/4 // 6
int8 (specif_number-def)/4 // 7
int8 (specif_number-def)/4 // 8
int8 (specif_number-def)/4 // 9
int8 0 // :
int8 0 // ;
int8 0 // <
int8 0 // =
int8 0 // >
int8 0 // ?
int8 0 // @
int8 (specif_hex-def)/4 // A: hexadecimal float
int8 0 // B
int8 0 // C
int8 0 // D
int8 (specif_float-def)/4 // E: float
int8 (specif_float-def)/4 // F: float
int8 (specif_float-def)/4 // G: float
int8 0 // H
int8 0 // I
int8 0 // J
int8 0 // K
int8 (specif_l-def)/4 // L: long (long double)
int8 0 // M
int8 0 // N
int8 0 // O
int8 0 // P
int8 0 // Q
int8 0 // R
int8 0 // S
int8 0 // T
int8 0 // U
int8 0 // V
int8 0 // W
int8 (specif_hex-def)/4 // X: hexadecimal
int8 0 // Y
int8 0 // Z
int8 0 // [
int8 0 // \
int8 0 // ]
int8 0 // ^
int8 0 // _
int8 0 // `
int8 (specif_hex-def)/4 // a: hexadecimal float
int8 0 // b
int8 (specif_char-def)/4 // c: character
int8 (specif_dec-def)/4 // d: signed decimal
int8 (specif_float-def)/4 // e: float
int8 (specif_float-def)/4 // f: float
int8 (specif_float-def)/4 // g: float
int8 (specif_h-def)/4 // h: short
int8 (specif_dec-def)/4 // i: signed decimal
int8 (specif_l-def)/4 // j: intmax_t
int8 0 // k
int8 (specif_l-def)/4 // l: long
int8 0 // m
int8 (specif_num-def)/4 // n: read number of characters printed so far
int8 0 // o
int8 (specif_hex-def)/4 // p: pointer, print as hexadecimal
int8 0 // q
int8 0 // r
int8 (specif_string-def)/4 // s: string
int8 (specif_l-def)/4 // t: ptrdiff_t
int8 (specif_uns-def)/4 // u: unsigned decimal
int8 0 // v
int8 0 // w
int8 (specif_hex-def)/4 // x: hexadecimal
int8 0 // y
int8 (specif_l-def)/4 // z: size_t
const end
code section execute align = 4 // code section
// _printf_light: print formatted string to stdout
// parameters: r0: format string, r1: parameter list
_printf_light function public reguse = 0xF, 0
int64 r2 = r0 // format string
int64 r3 = r1 // parameter list
int64 sp -= 10*8 // start saving registers
int64 [sp+0x30] = r10 // save r10. The rest are saved under printf_generic
int64 r10 = address ([char_to_stdout])
jump printf_generic
// _sprintf_light: print formatted string to string buffer
// parameters: r0: destination string, r1: format string, r2: parameter list
_sprintf_light function public reguse = 0xF, 0
int64 r3 = r2 // parameter list
int64 r2 = r1 // format string
int64 r1 = -1 // character count limit = UINT_MAX
int64 sp -= 10*8 // start saving registers
int64 [sp+0x30] = r10 // save r10. The rest are saved under printf_generic
int64 r10 = address ([char_to_string])
jump printf_generic
// _snprintf_light: print formatted string to string buffer with limit
// parameters: r0: destination string, r1: length limit, r2: format string, r3: parameter list
_snprintf_light function public reguse = 0xF, 0
int64 r1-- // character count limit. make space for terminating zero
int64 sp -= 10*8 // start saving registers
int64 [sp+0x30] = r10 // save r10. The rest are saved under printf_generic
int64 r10 = address ([char_to_string])
// continue in printf_generic
printf_generic: // common procedure for all printf variants
// save r4 - r13
//int64 sp -= 10*8 // this is done above
int64 [sp+0x00] = r4
int64 [sp+0x08] = r5
int64 [sp+0x10] = r6
int64 [sp+0x18] = r7
int64 [sp+0x20] = r8
int64 [sp+0x28] = r9
// int64 [sp+0x30] = r10 // r10 saved above
int64 [sp+0x38] = r11
int64 [sp+0x40] = r12
int64 [sp+0x48] = r13
if (int64 r2 == 0) {jump finish} // format string pointer is null
int r13 = 0 // reset field width
int r11 = 0 // reset modifiers
int r12 = 0 // state start
// loop through format string
while (true) {
int8 r8 = [r2] // read character from format string
if (int8+ r8 == 0) {break} // end of format string
int64 r2++ // increment format string pointer
if (int r12 == 0) { // state start
if (int8+ r8 == '%') {
int r12 = 1 // state after '%'
}
else {
call (r10) // print character from format string
}
nop
}
else { // after '%' or modifier
int r6 = r8 - ' ' // table index
int64 r4 = address ([unknown_character])
if (uint r6 > 91) {
call (r4) // call unknown_character
}
else {
int64 r5 = address ([call_table])
int8 call_relative (r4, [r5 + r6*1]) // dispatch format specifier or modifier
}
}
}
finish:
// if printing to string, insert terminating zero
int64 r4 = address ([char_to_string])
if (uint64 r10 >= r4) {
int r4 = 0
int8 [r0] = r4
}
int64 r0 = r9 // return number of characters written
// restore r4 - r13
int64 r4 = [sp+0x00]
int64 r5 = [sp+0x08]
int64 r6 = [sp+0x10]
int64 r7 = [sp+0x18]
int64 r8 = [sp+0x20]
int64 r9 = [sp+0x28]
int64 r10 = [sp+0x30]
int64 r11 = [sp+0x38]
int64 r12 = [sp+0x40]
int64 r13 = [sp+0x48]
int64 sp += 10*8
return // return from _printf_light, etc.
/////////////////////////////////////////////////////////////
// subfunctions for different characters in format string
/////////////////////////////////////////////////////////////
specif_space: // ' ': print space or minus
if (int r12 != 1) {jump unknown_character}
int r11 |= 8 // set modifier flag
return
specif_plus: // +: print sign
if (int r12 != 1) {jump unknown_character}
int r11 |= 4 // set modifier flag
return
specif_minus: // -: left justified
if (int r12 != 1) {jump unknown_character}
int r11 |= 1 // set modifier flag
return
specif_hash: // hash sign: print prefix 0x
if (int r12 != 1) {jump unknown_character}
int r11 |= 0x10 // set modifier flag
return
specif_h: // h: short
int r4 = test_bits_or(r11, 0x40) // is there a preceding h?
int r11 |= 0x40 // set modifier flag h
int r11 |= 0x80, mask = r4 // set modifier flag hh
int r12 = 3 // state after sub_specifier
return
specif_l: // l: long
int r11 |= 0x20 // set modifier flag l
int r12 = 3 // state after sub_specifier
return
specif_percent: // %: print percent sign
jump unknown_character // just print % sign and reset state
specif_star: // *: width specified by parameter
if (int r12 != 1) {jump unknown_character}
int r13 = [r3] // read width from paramter
int64 r3 += 8
int r12 = 2 // state after width
int r11 |= 0x100 // set modifier flag
return
specif_number: // 0-9
if (int r12 == 1) {
if (int r8 == '0') { // leading '0' means print leading zeroes
int r11 |= 2 // set modifier flag 2
return
}
}
// number specifies width
// width = previous_width * 10 + new_digit
int r4 = r13 << 3 // multiply width by 10
int r13 <<= 1
int r13 += r4
int r8 -= '0' // convert from ASCII
int r13 += r8 // new width
int r12 = 2 // state after width
int r11 |= 0x100 // set modifier flag
return
// subfunction for writing to stdout
char_to_stdout:
int8 output(r8, r8, 10) // write to stdout
int64 r9++ // count characters written
return
// subfunction for writing to string
char_to_string:
int64 r9++ // count characters written or potentially written
if (uint64 r9 > r1) { // compare with string length limit
jump char_to_string9 // stop printing
}
int8 [r0] = r8 // write to string
int64 r0++ // increment string pointer
char_to_string9:
return
// %n: read number of characters printed so far
specif_num: // n: read number of characters printed so far
int64 r4 = [r3] // read pointer from parameter list
int64 r3 += 8 // increment parameter list
int32 [r4] = r9 // save number of characters written
jump reset_state
// %c: Print character
specif_char: // c: print character
int r13-- // number of leading or trailing spaces to pring
if (int !(r11 & 1)) { // field is right justified. print leading spaces
int r8 = ' ' // leading spaces
for (int; r13 > 0; r13--) {
call (r10) // print space
}
}
int8 r8 = [r3] // read character from parameter list
int64 r3 += 8 // increment parameter list
call (r10) // print character
int r8 = ' ' // print any trailing spaces
for (int; r13 > 0; r13--) {
call (r10) // print space
}
jump reset_state
// %s: Print string
specif_string: // s: string
int64 r6 = [r3] // read string pointer from parameter list
int64 r3 += 8 // increment parameter list
if (int64 r6 == 0) {jump unknown_character} // null string
int r4 = r11 ^ 1 // check if right justified
int16+ test_bits_and(r4, 0x101), jump_false specif_string2
// string is right justified with specified width. check if leading spaces are needed
for (int r5 = 0; r5 < r13; r5++) {
int8 r8 = [r6+r5] // read string character
if (int8+ r8 == 0) {break} // string is shorter. leading spaces needed
}
// print leading spaces
int r8 = ' '
for (int ; r5 < r13; r5++) {
call (r10) // print space
}
int r13 = 0 // avoid printing trailing spaces also
specif_string2:
while (true) {
int8 r8 = [r6] // read character from string
if (int8+ r8 == 0) {break} // end of string
int64 r6++ // increment string pointer
call (r10) // print character
int r13-- // count down field width
}
// print any trailing space
int r8 = ' '
while (int r13 > 0) {
call (r10) // print character
int r13-- // count down field width
}
jump reset_state
// %e, %f, %g: Print floating point number
specif_float:
//jump specif_float1 // (intermediate jump target specif_float placed here to avoid overflow in call table)
// float not implemented. print as %#LX
int r11 |= 0x30 // print 0x prefix, 64 bits
jump specif_hex
// reference point, default in call table, print unknown character:
def: // default, reference point in call table
unknown_character: // unknown character after '%'
call r10 // print character
//jump reset_state
reset_state: // reset state after '%' command
int r11 = 0 // reset modifiers
int r12 = 0 // state start
int r13 = 0 // reset field width
return
// %x: Print hexadecimal
specif_hex: // X: hexadecimal
int r7 = r8 & 0x20 // is lower case
int64 r4 = [r3] // read integer from parameter list
int64 r3 += 8 // increment parameter list
if (int !(r11 & 0x20)) { // check if long int
int32 r4 = r4 // not long. truncate to 32 bits
}
specif_hex2: // entry from %i (decimal) if number too big
int64 r5 = bitscan(r4, 1) // find number of bits
uint32 r5 >>= 2
int32 r5++ // number of digits to print
int r13 -= r5 // number of leading or trailing spaces to print
int r6 = test_bit(r11, 4) // '#' option
int r13 -= 2, mask = r6 // make space of 0x prefix
if (int !(r11 & 1)) { // field is right justified. print leading spaces
int r8 = ' ' // leading spaces
int r6 = test_bit(r11, 1) // get bit 1: leading zeroes
int r8 = '0', mask=r6, fallback=r8 // leading zeroes instead of leading spaces
while (int r13 > 0) { // print r13 leading spaces or zeroes
call r10
int r13--
}
}
if (int r11 & 0x10) { // '#' flag. Print 0x prefix
int r8 = '0'
call r10
int r8 = 'X' | r7 // 'x' or 'X'
call r10
}
// convert to hexadecimal
if (int r5 > 8) { // must use 64 bits
int r6 = 16 - r5 // number of digits to skip
int r6 <<= 2 // number of bits to skip
uint64 r4 <<= r6 // remove leading zero bits
for (int ; r5 > 0; r5--) { // loop for r5 digits
uint64 r4 = rotate(r4, 4) // get digit into low position
int r8 = r4 & 0xF // get digit
int r8 += '0' // convert to ASCII
int r6 = r8 > '9' // digit is A - F
int r8 += 7, mask = r6 // add 7 to get letter A - F
int r8 |= r7 // lower case
call r10 // print character
}
}
else { // use 32 bits. CPU may not support 64 bits
int r6 = 8 - r5 // number of digits to skip
int r6 <<= 2 // number of bits to skip
uint32 r4 <<= r6 // remove leading zero bits
for (int ; r5 > 0; r5--) { // loop for r5 digits
uint32 r4 = rotate(r4, 4) // get digit into low position
int r8 = r4 & 0xF // get digit
int r8 += '0' // convert to ASCII
int r6 = r8 > '9' // digit is A - F
int r8 += 7, mask = r6 // add 7 to get letter A - F
int r8 |= r7 // lower case
call r10 // print character
}
}
// print any trailing spaces
int r8 = ' ' // trailing spaces
while (int r13 > 0) { // print r13 trailing spaces
call r10
int r13--
}
jump reset_state
// %i, %d: Print signed decimal integer
specif_dec: // i: signed decimal
int64 r4 = [r3] // read integer from parameter list
int64 r3 += 8 // increment parameter list
if (int r11 & 0x20) { // %li: 64-bit integer
int64 r5 = test_bit(r4, 63) // get sign bit
int64 r4 = -r4, mask = r5 // change sign if negative
int r11 |= 0x200, mask = r5 // set bit to remember negative
int64 r6 = bitscan(r4, 1) // find number of bits
if (int r6 > 31) { // cannot handle 64 bits decimal. Do hexadecimal instead
int r11 |= 0x11 // prepare for hexadecimal escape. get 0x prefix and left justify
int r7 = 0 // use upper case for hexadecimal escape
if (int8+ r5 & 1) {
int r8 = '-' // print '-'
call r10
}
jump specif_hex2 // print as hexadecimal
}
}
else {
if (int r11 & 0x80) { // %hhi: int8
int32 r5 = test_bit(r4, 7) // get sign bit
int8 r4 = -r4, mask = r5 // change sign if negative. truncate to 8 bits
int r11 |= 0x200, mask = r5 // set bit to remember negative
}
else {
if (int r11 & 0x40) { // %hhi: int16
int32 r5 = test_bit(r4, 15) // get sign bit
int16 r4 = -r4, mask = r5 // change sign if negative. truncate to 16 bits
int r11 |= 0x200, mask = r5 // set bit to remember negative
}
else {
// %i: int32
int32 r5 = test_bit(r4, 31) // get sign bit
int32 r4 = -r4, mask = r5 // change sign if negative. truncate to 16 bits
int r11 |= 0x200, mask = r5 // set bit to remember negative
}
}
}
jump specif_uns2 // sign has been stored in r11. continue in unsigned
// %u: Print unsigned decimal integer
specif_uns: // u: unsigned decimal
int64 r4 = [r3] // read integer from parameter list
int64 r3 += 8 // increment parameter list
if (int r11 & 0x20) { // %li: 64-bit integer
int64 r6 = bitscan(r4, 1) // find number of bits
int r8 |= 0x10 // prepare for hexadecimal escape. get 0x prefix
int r7 = 0 // use upper case for hexadecimal escape
if (int r6 > 31) {jump specif_hex2}// cannot handle 64 bits decimal. Do hexadecimal instead
}
specif_uns2:
int64 sp -= 8 // save r14
int64 [sp] = r14
// 32 bit decimal signed or unsigned
// First two BCD digits are made with simple subtraction to avoid the need for a larger bit field
int r5 = 0 // upper two BCD digits
while (uint32 r4 >= 1000000000) {
uint32 r4 -= 1000000000
uint32 r5 += 0x10
}
while (uint32 r4 >= 100000000) {
uint32 r4 -= 100000000
uint32 r5 += 0x01
}
// Generate 8 BCD digits using double dabble algorithm
int32 r14 = 0 // generate BCD in r14
for (int r6 = 0; r6 < 32; r6++) { // loop for 32 bits
int32 r7 = r14 + 0x33333333 // digit values 5-9 will set bit 3 in each 4-bit nibble
int32 r7 &= 0x88888888 // isolate bit 3 in each nibble
int32 r8 = r7 >> 3 // generate value 3 in nibbles with value 5-9
int32 r7 >>= 2
int32 r7 |= r8 // this will have 3 for each nibble with a value 5-9
int32 r14 += r7 // add 3 to nibble values 5-9 to generate 8-12
int32 r14 = funnel_shift(r4, r14, 31) // shift most significant bit of r4 into r14
int32 r4 <<= 1
}
// r5:r14 = BCD value
// determine width
int r6 = bitscan(r14, 1) // number of significant bits
uint r6 >>= 2 // number of significant digits in low part
int r6++ // number of digits in low part
if (int r5 != 0) { // high part is nonzero
int r6 = bitscan(r5, 1) // find number of digits in high part
uint r6 >>= 2
int r6 += 9 // number of digits total
}
int r7 = test_bits_or(r11, 0x20C) // leading sign needed
int r6 += r7 // number of characters needed
int r13 -= r6 // number of leading or trailing spaces needed
if (int !(r11 & 1)) { // right justified
int r6 = r13 > 0 && r7 // leading sign && leading spaces
int r4 = test_bit(r11, 1), options=1, fallback=r6 // leading zeroes and leading sign. sign must come first
int r8 = ' ' // leading sign to print
int r6 = test_bit(r11, 2) // flag for '+' prefix
int r8 = '+', mask=r6, fallback=r8 // leading + required if not negative
int r6 = test_bit(r11, 9) // flag for negative
int r8 = '-', mask=r6, fallback=r8 // leading -. value is negative
if (int r4 & 1) { // sign must come before leading zeroes
call r10 // print leading sign
int r7 = 0 // remember leading sign has been written
}
// print leading spaces or zeroes
int r8 = ' ' // space
int r6 = test_bit(r11, 1) // flag for leading zeroes
int r8 = '0', mask=r6, fallback=r8
while (int r13 > 0) { // write leading spaces or zeroes
call r10
int r13--
}
}
if (int r7 & 1) { // sign after leading spaces
int r8 = ' ' // space
int r6 = test_bit(r11, 2) // flag for '+' prefix
int r8 = '+', mask=r6, fallback=r8 // leading + required if not negative
int r6 = test_bit(r11, 9) // flag for negative
int r8 = '-', mask=r6, fallback=r8 // leading -. value is negative
call r10 // write sign
}
int r4 = 0 // remember if first digit has been printed
// print high two digits
uint32 r5 <<= 24 // left justify high part
for (int r6 = 2; r6 > 0; r6--) { // print two high digits if any
int32 r5 = rotate(r5, 4) // get most significant digit first
int8 r8 = r5 & 0x0F
int r4 = (r8 != 0) || r4 // digit has been printed
int8 r8 += '0' // convert to ASCII
if (int r4 != 0) {
call r10 // print character to stdout
}
}
// print low 8 decimal digits
for (int r6 = 8; r6 > 0; r6--) {
int32 r14 = rotate(r14, 4) // get most significant digit first
int8 r8 = r14 & 0x0F
int r4 = (r8 != 0) || r4 // digit has been printed
int r4 = (r6 == 1) || r4 // last digit must be printed
int8 r8 += '0' // convert to ASCII
if (int r4 != 0) {
call r10 // print character to stdout
}
}
// print trailing spaces
int r8 = ' ' // space
while (int r13 > 0) { // write trailing spaces
call r10
int r13--
}
int64 r14 = [sp] // restore r14
int64 sp += 8
jump reset_state // finished
// %e, %f, %g: Print floating point number. not implemented
specif_float1:
nop
jump reset_state // finished
code end