1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley Software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8:     .ascii  "@(#)doprnt.c	5.2 (Berkeley) 6/6/85"
   9: #endif
  10: 
  11:     # C library -- conversions
  12: 
  13: .globl  __doprnt
  14: .globl  __strout
  15: 
  16: #define flags r10
  17: #define literb 0
  18: #define liter 1
  19: #define ndfndb 0
  20: #define ndfnd 1
  21: #define ljustb 1
  22: #define ljust 2
  23: #define zfillb 2
  24: #define zfill 4
  25: #define precb 3
  26: #define prec 8
  27: #define psignb 4
  28: #define psign 16
  29: #define gflagb 5
  30: #define gflag 32
  31: #define width r9
  32: #define ndigit r8
  33: #define fdesc -4(fp)
  34: #define exp -8(fp)
  35: #define sign -9(fp)
  36:     .set one,010            # 1.0 in floating immediate
  37:     .set ch.zer,'0			# cpp doesn't like single appostrophes
  38: 
  39:     .align  1
  40: __doprnt:
  41:     .word   0xfc0           # uses r11-r6
  42:     subl2 $128,sp
  43:     movl 4(ap),r11          # addr of format string
  44:     movl 12(ap),fdesc       # output FILE ptr
  45:     movl 8(ap),ap           # addr of first arg
  46: loop:
  47:     movl r11,r0         # current point in format
  48:     bicl2 $liter,flags      # no literal characters yet
  49: L1: movb (r11)+,width       # next character of format
  50:     beql L2             # end of format string
  51:     cmpb width,$'%
  52:     beql L2             # warning character
  53:     bisl2 $liter,flags      # literal character
  54:     jbr L1
  55: L2: blbc flags,L3           # bbc $literb,flags,L3 # no literals in format
  56:     pushl fdesc         # file pointer
  57:     pushl $0            # no left/right adjust
  58:     pushl r0            # addr
  59:     subl3 r0,r11,r1         # length
  60:     subl3 $1,r1,-(sp)       # % or null not part of literal
  61:     calls $4,__strout       # dump the literal
  62: L3:
  63:     blbs width,L4           # % is odd; end of format?
  64:     ret             # yes
  65: 
  66:     # htab overlaps last 16 characters of ftab
  67: ftab:   .byte    0, 0, 0,'c,'d,'e,'f,'g, 0, 0, 0,'+,'l,'-,'.,'o
  68: htab:   .byte   '0,'1,'2,'3,'4,'5,'6,'7,'8,'9,'a,'b,'c,'d,'e,'f
  69: 
  70: L4: movl sp,r5          # reset output buffer pointer
  71:     clrq r9             # width; flags ljustb,ndfndb,zfillb
  72: L4a:    movzbl (r11)+,r0        # supposed format
  73:     extzv $0,$5,r0,r1        # bottom 5 bits
  74: L4b:    cmpb r0,ftab[r1]        # good enough?
  75:     jneq L6             # no
  76: L4c:    casel r1,$3,$22         # yes
  77: L5: .word charac-L5         # c
  78:     .word decimal-L5        # d
  79:     .word scien-L5          # e
  80:     .word float-L5          # f
  81:     .word general-L5        # g
  82:     .word L6-L5         # h
  83:     .word L6-L5         # i
  84:     .word L6-L5         # j
  85:     .word plus-L5           # +
  86:     .word longorunsg-L5     # l
  87:     .word minus-L5          # -
  88:     .word dot-L5            # .
  89:     .word octal-L5          # o
  90:     .word gnum0-L5          # 0
  91:     .word gnum-L5           # 1
  92:     .word gnum-L5           # 2
  93:     .word gnum-L5           # 3
  94:     .word gnum-L5           # 4
  95:     .word gnum-L5           # 5
  96:     .word gnum-L5           # 6
  97:     .word gnum-L5           # 7
  98:     .word gnum-L5           # 8
  99:     .word gnum-L5           # 9
 100: 
 101: L6: jbcs $5,r0,L4b          # capitals same as small
 102:     cmpb r0,$'s
 103:     jeql string
 104:     cmpb r0,$'x
 105:     jeql hex
 106:     cmpb r0,$'u
 107:     jeql unsigned
 108:     cmpb r0,$'r
 109:     jeql remote
 110:     movzbl -1(r11),r0       # orginal "format" character
 111:     cmpb r0,$'*
 112:     jeql indir
 113: L9: movb r0,(r5)+           # print the unfound character
 114:     jbr prbuf
 115: 
 116: nulstr:
 117:     .byte '(,'n,'u,'l,'l,'),0
 118: 
 119: string:
 120:     movl ndigit,r0
 121:     jbs $precb,flags,L20        # max length was specified
 122:     mnegl $1,r0         # default max length
 123: L20:    movl (ap)+,r2           # addr first byte
 124:     bneq L21
 125:     movab nulstr,r2
 126: L21:    locc $0,r0,(r2)         # find the zero at the end
 127:     movl r1,r5          # addr last byte +1
 128:     movl r2,r1          # addr first byte
 129:     jbr prstr
 130: 
 131: 
 132: longorunsg:
 133:     movb (r11)+,r0
 134:     cmpb r0,$'o
 135:     jeql loct
 136:     cmpb r0,$'x
 137:     jeql lhex
 138:     cmpb r0,$'d
 139:     jeql long
 140:     cmpb r0,$'u
 141:     jeql lunsigned
 142:     decl r11
 143:     jbr unsigned
 144: 
 145: loct:
 146: octal:
 147:     movl $30,r2         # init position
 148:     movl $3,r3          # field width
 149:     movl $10,r4         # result length -1
 150:     jbr L10
 151: 
 152: lhex:
 153: hex:
 154:     movl $28,r2         # init position
 155:     movl $4,r3          # field width
 156:     movl $7,r4          # result length -1
 157: L10:    mnegl r3,r6         # increment
 158:     clrl r1
 159:     movl (ap)+,r0           # fetch arg
 160: L11:    extzv r2,r3,r0,r1       # pull out a digit
 161:     movb htab[r1],(r5)+     # convert to character
 162: L12:    acbl $0,r6,r2,L11       # continue until done
 163:     clrb (r5)           # flag end
 164:     skpc $'0,r4,(sp)		# skip over leading zeroes
 165:     jbr prstr
 166: 
 167: patdec:                 # editpc pattern for decimal printing
 168:     .byte 0xA9          # eo$float 9
 169:     .byte 0x01          # eo$end_float
 170:     .byte 0x91          # eo$move 1
 171:     .byte 0             # eo$end
 172: 
 173: long:
 174: decimal:
 175:     cvtlp (ap)+,$10,(sp)        # 10 digits max
 176: L14:    editpc $10,(sp),patdec,8(sp)    # ascii at 8(sp); r5=end+1
 177:     skpc $' ,$10,8(sp)		# skip leading blanks; r1=first
 178: 
 179: prstr:          # r1=addr first byte; r5=addr last byte +1
 180:     cvtbl $' ,-(sp)			# blank fill
 181:     jbc $zfillb,flags,L15
 182:     cvtbl $'0,(sp)			# zero fill
 183: L15:    pushl fdesc         # FILE
 184:     subl2 r1,r5         # r5=actual length=end+1-first
 185:     subl3 r5,width,r0       # if >0, how much to fill
 186:     bgeq L24
 187:     clrl r0             # no fill
 188: L24:    jbs $ljustb,flags,L25
 189:     mnegl r0,r0
 190: L25:    pushl r0            # fill count
 191:     pushl r1            # addr first byte
 192:     pushl r5            # length
 193:     calls $5,__strout
 194:     jbr loop
 195: 
 196: pone:   .byte   0x1C            # packed 1
 197: 
 198: unsigned:
 199: lunsigned:
 200:     extzv $1,$31,(ap),r0        # right shift logical 1 bit
 201:     cvtlp r0,$10,(sp)       # convert [n/2] to packed
 202:     movp $10,(sp),8(sp)     # copy packed
 203:     addp4 $10,8(sp),$10,(sp)    # 2*[n/2] in packed, at (sp)
 204:     blbc (ap)+,L14          # n was even
 205:     addp4 $1,pone,$10,(sp)      # n was odd
 206:     jbr L14
 207: 
 208: charac:
 209:     movl $4,r0          # chars per word
 210: L18:    movb (ap)+,(r5)+        # transfer char
 211:     bneq L19
 212:     decl r5             # omit null characters
 213: L19:    sobgtr r0,L18
 214: 
 215: prbuf:
 216:     movl sp,r1          # addr first byte
 217:     jbr prstr
 218: 
 219: plus:   bisl2 $psign,flags      # always print sign for floats
 220:     jbr L4a
 221: minus:  bisl2 $ljust,flags      # left justification, please
 222:     jbr L4a
 223: gnum0:  jbs $ndfndb,flags,gnum
 224:     jbs $precb,flags,gnump      # ignore when reading precision
 225:     bisl2 $zfill,flags      # leading zero fill, please
 226: gnum:   jbs $precb,flags,gnump
 227:     moval (width)[width],width  # width *= 5;
 228:     movaw -ch.zer(r0)[width],width  # width = 2*witdh + r0 - '0';
 229:     jbr gnumd
 230: gnump:  moval (ndigit)[ndigit],ndigit   # ndigit *= 5;
 231:     movaw -ch.zer(r0)[ndigit],ndigit # ndigit = 2*ndigit + r0 - '0';
 232: gnumd:  bisl2 $ndfnd,flags      # digit seen
 233:     jbr L4a
 234: dot:    clrl ndigit         # start on the precision
 235:     bisl2 $prec,flags
 236:     bicl2 $ndfnd,flags
 237:     jbr L4a
 238: indir:  movl (ap)+,ndigit       # width specified by parameter
 239:     jbr gnumd
 240: remote: movl (ap)+,ap
 241:     movl (ap)+,r11
 242:     jbr loop
 243: 
 244: float:
 245:     bsbw fltcvt
 246: fltg:   jbs $ndfndb,flags,float1
 247:     movl $6,ndigit          # default # digits to right of decpt.
 248: float1: addl3 exp,ndigit,r7
 249:     movl r7,r6          # for later "underflow" checking
 250:     bgeq fxplrd
 251:     clrl r7             # poor programmer planning
 252: fxplrd: cmpl r7,$31         # expressible in packed decimal?
 253:     bleq fnarro         # yes
 254:     movl $31,r7
 255: fnarro: subl3 $17,r7,r0         # where to round
 256:     ashp r0,$17,(sp),$5,r7,16(sp)   # do it
 257:     bvc fnovfl
 258:     # band-aid for microcode error (spurious overflow)
 259:     clrl r0             # assume even length result
 260:     jlbc r7,fleven          # right
 261:     movl $4,r0          # odd length result
 262: fleven: cmpv r0,$4,16(sp),$0        # top digit zero iff true overflow
 263:     bneq fnovfl
 264:     # end band-aid
 265:     aobleq $0,r6,fnovfl     # if "underflow" then jump
 266:     movl r7,r0
 267:     incl exp
 268:     incl r7
 269:     ashp r0,$1,pone,$0,r7,16(sp)
 270:     ashl $-1,r7,r0          # displ to last byte
 271:     bisb2 sign,16(sp)[r0]       # insert sign
 272: fnovfl:
 273:     movc3 $4,patsci,(sp)
 274:     clrl r6             # # digits moved so far
 275:     movl exp,r0
 276:     bleq fexpng
 277:     bsbb patmov         # digits to left of decpt.
 278: fexpng: tstl ndigit
 279:     jeql fnodp
 280:     movc3 $2,fpatdp,(r3)
 281:     tstl exp
 282:     bgeq fxppos
 283:     addl3 exp,ndigit,r6
 284:     bgeq  flfakl
 285:     clrl r6             # it's all fill
 286: flfakl: subl3 r6,$31,r6         # fake length for patmov
 287: flfill: movc3 $2,fpatzf,(r3)        # zero fill to right of dec.pt
 288: fxppos: movl ndigit,r0
 289:     bsbb patmov
 290: fnodp:  sobgeq r6,fledit        # must move at least 1 digit
 291:     movl $31,r6         # none moved; fake it
 292:     aobleq $1,ndigit,flfill     # with a one-character zero fill
 293: fledit: editpc r7,16(sp),(sp),32(sp)
 294:     jbr prflt
 295: 
 296: patexp: .byte   0x03            # eo$set_signif
 297:     .byte   0x44,'e			# eo$insert 'e
 298:     .byte   0x42,'+			# eo$load_plus '+
 299:     .byte   0x04            # eo$store_sign
 300:     .byte   0x92            # eo$move 2
 301:     .byte   0           # eo$end
 302: patsci: .byte   0x42,'+			# eo$load_plus '+
 303:     .byte   0x03            # eo$set_signif
 304:     .byte   0x04            # eo$store_sign
 305:     .byte   0x91            # eo$move 1
 306: fpatdp: .byte   0x44,'.			# eo$insert '.
 307: fpatzf: .byte   0x40,'0			# eo$load_fill '0
 308: 
 309:     # construct pattern at (r3) to move  r0  digits in  editpc;
 310:     #  r6  digits already moved for this number
 311: patmov:
 312:     movb $0x90,r2           # eo$move
 313:     subl3 r6,$31,r1         # # digits remaining in packed
 314:     addl2 r0,r6
 315:     cmpl r0,r1          # enough digits remaining?
 316:     bleq patsml         # yes
 317:     tstl exp            # zero 'fill'; before or after rest?
 318:     bgeq pataft         # after
 319:     pushl r1            # # digits remaining
 320:     movb $0x80,r2           # eo$fill
 321:     subl3 $31,r6,r0         # number of fill bytes
 322:     bsbb patsml         # recursion!
 323:     movl (sp)+,r0
 324:     movb $0x90,r2           # eo$move
 325:     jbr patsml
 326: pataft: movl r1,r0          # last of the 31
 327:     bsbb patsml         # recursion!
 328:     subl3 $31,r6,r0         # number of fill bytes
 329:     movb $0x80,r2           # eo$fill
 330: patsml: tstl r0
 331:     bleq patzer         # DEC doesn't like repetition counts of 0
 332:     mnegl $15,r1            # 15 digits at a time
 333:     subl2 r1,r0         # counteract acbl
 334:     jbr pattst
 335: patmlp: bisb3 r2,$15,(r3)+      # 15
 336: pattst: acbl $16,r1,r0,patmlp       # until <= 15 left
 337:     bisb3 r2,r0,(r3)+       # rest
 338: patzer: clrb (r3)           # eo$end
 339:     rsb
 340: 
 341: scien:
 342:     bsbw fltcvt         # get packed digits
 343: scig:   incl ndigit
 344:     jbs $ndfndb,flags,L23
 345:     movl $7,ndigit
 346: L23:    subl3 $17,ndigit,r0     # rounding position
 347:     ashp r0,$17,(sp),$5,ndigit,16(sp) # shift and round
 348:     bvc snovfl
 349:     # band-aid for microcode error (spurious overflow)
 350:     clrl r0             # assume even length result
 351:     jlbc ndigit,sceven      # right
 352:     movl $4,r0          # odd length result
 353: sceven: cmpv r0,$4,16(sp),$0        # top digit zero iff true overflow
 354:     bneq snovfl
 355:     # end band-aid
 356:     incl exp            # rounding overflowed to 100...
 357:     subl3 $1,ndigit,r0
 358:     ashp r0,$1,pone,$0,ndigit,16(sp)
 359:     ashl $-1,ndigit,r0      # displ to last byte
 360:     bisb2 sign,16(sp)[r0]       # insert sign
 361: snovfl:
 362:     jbc $gflagb,flags,enotg     # not %g format
 363:  # find trailing zeroes in packed number
 364:     ashl $-1,ndigit,r0
 365:     addl2 r3,r0         # addr of l.s.digit and sign
 366:     movl $4,r1          # bit position of digit
 367:     movl ndigit,r7          # current length of packed
 368:     jbr gtz
 369: gtz1:   xorl2 $4,r1         # position of next digit
 370:     bneq gtz            # same byte
 371:     decl r0             # different byte
 372: gtz:    cmpv r1,$4,(r0),$0      # a trailing zero?
 373:     jneq gntz
 374:     sobgtr r7,gtz1
 375:     incl r7
 376: gntz:                   # r7: minimum width of fraction
 377:     cmpl exp,$-4
 378:     jleq eg             # small exponents use %e
 379:     subl3 r7,exp,r0
 380:     cmpl $5,r0
 381:     jleq eg             # so do (w+5) <= exp
 382:     tstl r0             # rest use %f
 383:     jleq fg             # did we trim too many trailing zeroes?
 384:     movl exp,r7         # yes
 385: fg: subl3 ndigit,r7,r0
 386:     ashp r0,ndigit,16(sp),$0,r7,(sp)
 387:     movp r7,(sp),16(sp)
 388:     subl3 exp,r7,ndigit     # correct ndigit for %f
 389:     jbr fnovfl
 390: eg: subl3 ndigit,r7,r0
 391:     ashp r0,ndigit,16(sp),$0,r7,(sp)
 392:     movp r7,(sp),16(sp)
 393:     movl r7,ndigit          # packed number has been trimmed
 394: enotg:
 395:     movc3 $7,patsci,(sp)
 396:     movl $1,r6          # 1P
 397:     subl3 $1,ndigit,r0      # digits after dec.pt
 398:     bsbw patmov
 399:     editpc ndigit,16(sp),(sp),32(sp)    # 32(sp)->result, r5->(end+1)
 400:     decl exp            # compensate: 1 digit left of dec.pt
 401:     cvtlp exp,$2,(sp)       # exponent
 402:     editpc $2,(sp),patexp,(r5)
 403: prflt:  movab 32(sp),r1
 404:     jbs $psignb,flags,prflt1
 405:     cmpb (r1)+,$'+
 406:     beql prflt1
 407:     decl r1
 408: prflt1: skpc $' ,$63,(r1)
 409:     jbr prstr
 410: 
 411: general:
 412:     jbcs $gflagb,flags,scien
 413:     jbr scien           # safety net
 414: 
 415:     # convert double-floating at (ap) to 17-digit packed at (sp),
 416:     # set 'sign' and 'exp', advance ap.
 417: fltcvt:
 418:     clrb sign
 419:     movd (ap)+,r5
 420:     jeql fzero
 421:     bgtr fpos
 422:     mnegd r5,r5
 423:     incb sign
 424: fpos:
 425:     extzv $7,$8,r5,r2       # exponent of 2
 426:     movaw -0600(r2)[r2],r2      # unbias and mult by 3
 427:     bgeq epos
 428:     subl2 $9,r2
 429: epos:   divl2 $10,r2
 430:     bsbb expten
 431:     cmpd r0,r5
 432:     bgtr ceil
 433:     incl r2
 434: ceil:   movl r2,exp
 435:     mnegl r2,r2
 436:     cmpl r2,$29         # 10^(29+9) is all we can handle
 437:     bleq getman
 438:     muld2 ten16,r5
 439:     subl2 $16,r2
 440: getman: addl2 $9,r2         # -ceil(log10(x)) + 9
 441:     bsbb expten
 442:     emodd r0,r4,r5,r0,r5        # (r0+r4)*r5; r0=int, r5=frac
 443: fz1:    cvtlp r0,$9,16(sp)      # leading 9 digits
 444:     ashp $8,$9,16(sp),$0,$17,4(sp)  # as top 9 of 17
 445:     emodd ten8,$0,r5,r0,r5
 446:     cvtlp r0,$8,16(sp)      # trailing 8 digits
 447:     addp4 $8,16(sp),$17,4(sp)   # combine leading and trailing
 448:     bisb2 sign,12(sp)       # and insert sign
 449:     rsb
 450: fzero:  clrl r0
 451:     movl $1,exp     # 0.000e+00 and 0.000 rather than 0.000e-01 and .000
 452:     jbr fz1
 453: 
 454:     # return 10^r2 as a double float in r0||r1 and 8 extra bits of precision in r4
 455:     # preserve r2, r5||r6
 456: expten:
 457:     movd $one,r0            # begin computing 10^exp10
 458:     clrl r4             # bit counter
 459:     movad ten1,r3           # table address
 460:     tstl r2
 461:     bgeq e10lp
 462:     mnegl r2,r2         # get absolute value
 463:     jbss $6,r2,e10lp        # flag as negative
 464: e10lp:  jbc r4,r2,el1           # want this power?
 465:     muld2 (r3),r0           # yes
 466: el1:    addl2 $8,r3         # advance to next power
 467:     aobleq $5,r4,e10lp      # through 10^32
 468:     jbcc $6,r2,el2          # correct for negative exponent
 469:     divd3 r0,$one,r0        # by taking reciprocal
 470:     mnegl r2,r2
 471: el2:    clrl r4             # 8 extra bits of precision
 472:     rsb
 473: 
 474:     # powers of ten
 475:     .align  2
 476: ten1:   .word   0x4220,0,0,0
 477: ten2:   .word   0x43c8,0,0,0
 478: ten4:   .word   0x471c,0x4000,0,0
 479: ten8:   .word   0x4dbe,0xbc20,0,0
 480: ten16:  .word   0x5b0e,0x1bc9,0xbf04,0
 481: ten32:  .word   0x759d,0xc5ad,0xa82b,0x70b6

Defined functions

blbc defined in line 179; used 1 times
  • in line 55
clrb defined in line 179; used 1 times
cmpb defined in line 179; used 11 times
cvtlp defined in line 8; used 4 times
moval defined in line 179; never used
movb defined in line 179; used 6 times
movd defined in line 179; used 1 times
movl defined in line 179; used 34 times
movzbl defined in line 8; used 1 times
zer defined in line 179; used 1 times
  • in line 37

Defined macros

exp defined in line 34; used 16 times
fdesc defined in line 33; used 3 times
flags defined in line 16; used 22 times
gflag defined in line 30; never used
gflagb defined in line 29; never used
liter defined in line 18; never used
literb defined in line 17; never used
ljust defined in line 22; never used
ljustb defined in line 21; used 1 times
  • in line 71
ndfnd defined in line 20; never used
ndfndb defined in line 19; used 1 times
  • in line 71
ndigit defined in line 32; used 34 times
prec defined in line 26; never used
precb defined in line 25; never used
psign defined in line 28; never used
psignb defined in line 27; never used
sign defined in line 35; used 10 times
width defined in line 31; used 12 times
zfill defined in line 24; never used
zfillb defined in line 23; used 1 times
  • in line 71
Last modified: 1985-06-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1019
Valid CSS Valid XHTML 1.0 Strict