00001 dnl m4 processed 00002 changequote([[, ]])dnl 00003 # 00004 # RTL description for ST20 00005 # 00006 00007 MAXSIGN32 := 2**31 - 1; # all bits except sign bit are set 00008 SIGN_32_NEG := -2**31; 00009 INF := 0x7F800000; 00010 00011 INTEGER 00012 [ %Areg, %Breg, %Creg ] -> 0..2, 00013 %sp -> 3, 00014 %pc -> -1, 00015 [ %ZF, %CF ][1] -> -1 ; 00016 00017 define([[PUSH]], [[ 00018 *32* %Creg := %Breg 00019 *32* %Breg := %Areg 00020 *32* %Areg := $1]]) 00021 00022 define([[POPALL]], [[ 00023 *32* %Areg := %Breg 00024 *32* %Breg := %Creg]]) 00025 dnl# *32* %Creg := -1 00026 dnl ]]) 00027 00028 #A was replaced so dont overwrite it 00029 define([[POP1]], [[ 00030 *32* %Breg := %Creg]]) 00031 dnl# *32* %Creg := -1 00032 dnl ]]) 00033 define([[POP2]], [[]]) 00034 00035 #OP2(op) { 00036 # *32* %Areg := %Breg op %Areg 00037 # POP1() 00038 #}; 00039 00040 #OP2C(op) { 00041 # *32* %Areg := [%Breg op %Areg?1:0]; 00042 # POP1() 00043 #}; 00044 00045 adc val # add constant 00046 *32* %Areg := %Areg + val; 00047 add # add 00048 *32* %Areg := %Breg + %Areg 00049 POP1(); 00050 addc # add with carry 00051 _ ; 00052 ajw val # adjust work space 00053 *32* %sp := %sp + (4*val); 00054 andq # and 00055 *32* %Areg := %Breg & %Areg 00056 POP1(); 00057 arot # anti-rotate stack 00058 _ ; 00059 ashr # arithmetic shift right 00060 #OP2(">>"); 00061 *32* %Areg := %Breg >>A %Areg 00062 POP1(); 00063 biquad # biquad IIR filter step 00064 _ ; 00065 bitld # load bit 00066 _ ; 00067 bitmask # create bit mask 00068 _ ; 00069 bitst # store bit 00070 _ ; 00071 breakpoint # breakpoint 00072 _ ; 00073 cj val # conditional jump 00074 *32* tmp := %Areg 00075 *32* %ZF := 00076 *32* %Areg := [tmp = 0?%Areg:%Breg] 00077 *32* %Breg := [tmp = 0?%Breg:%Creg] 00078 *32* %pc := [tmp = 0?%pc+val:%pc]; 00079 cj1 val # conditional jump 00080 *32* tmp := %Areg 00081 *32* %ZF := 00082 *32* %Areg := [tmp = 0?%Areg:%Breg] 00083 *32* %Breg := [tmp = 0?%Breg:%Creg]; 00084 dequeue # dequeue a process 00085 _ ; 00086 divstep # divide step 00087 _ ; 00088 dup # duplicate 00089 PUSH(%Areg); 00090 ecall # exception call 00091 _ ; 00092 enqueue # enqueue a process 00093 _ ; 00094 eqc val # equals constant 00095 *32* %Areg := ; 00096 eret # exception return 00097 _ ; 00098 fcall val # function call 00099 _ ; 00100 gajw # general adjust workspace 00101 *32* tmp := %sp 00102 *32* %sp := %Areg 00103 *32* %Areg := tmp; 00104 gt # greater than 00105 #OP2C(">"); 00106 *32* %Areg := 00107 POP1(); 00108 gtu # greater than unsigned 00109 #OP2C(">"); 00110 *32* %Areg := 00111 POP1(); 00112 io # input/output 00113 _ ; 00114 j val # jump 00115 *32* %pc := %pc + val; 00116 # *32* %pc := val; 00117 jab # jump absolute 00118 _ ; 00119 lbinc # load byte and increment 00120 _ ; 00121 ldc val # load constant 00122 PUSH(val); 00123 ldl val # load local 00124 PUSH(m[%sp + (val*4)]{32}); 00125 ldlp val # load local pointer 00126 PUSH(%sp + (val*4)); 00127 ldnl val # load non-local 00128 *32* %Areg := m[%Areg + (val * 4)]{32}; 00129 ldnlp val # load non-local pointer 00130 *32* %Areg := %Areg + (val * 4); 00131 ldpi # load pointer to instruction 00132 *32* %Areg := %pc + (%Areg * 4); 00133 ldprodid # load product identity 00134 _ ; 00135 ldtdesc # load task descriptor 00136 _ ; 00137 lsinc # load sixteen and increment 00138 _ ; 00139 lsxinc # load sixteen sign extended and increment 00140 _ ; 00141 lwinc # load word and increment 00142 _ ; 00143 mac # multiply accumulate 00144 _ ; 00145 mul # multiply 00146 #OP2("*"); 00147 *32* %Areg := %Breg * %Areg 00148 POP1(); 00149 nfix val # negative prefix 00150 _ ; 00151 nop # no operation 00152 _ ; 00153 not # bitwise not 00154 *32* %Areg := ~%Areg; 00155 opr val # operate 00156 _ ; 00157 orq # or 00158 #OP2("|"); 00159 *32* %Areg := %Breg | %Areg 00160 POP1(); 00161 order # order 00162 _ ; 00163 orderu # unsigned order 00164 _ ; 00165 pfix val # prefix 00166 _ ; 00167 rev # reverse 00168 *32* tmp := %Areg 00169 *32* %Areg := %Breg 00170 *32* %Areg := tmp; 00171 rmw # read modify write 00172 _ ; 00173 rot # rotate stack 00174 _ ; 00175 run # run process 00176 _ ; 00177 saturate # saturate 00178 _ ; 00179 sbinc # store byte and increment 00180 _ ; 00181 shl # shift left 00182 #OP2("<<"); 00183 *32* %Areg := %Breg << %Areg 00184 POP1(); 00185 shr # shift right 00186 #OP2(">>"); 00187 *32* %Areg := %Breg >> %Areg 00188 POP1(); 00189 signal # signal 00190 _ ; 00191 smacinit # initialize short multiply accumulate loop 00192 _ ; 00193 smacloop # short multiply accumulate loop 00194 _ ; 00195 smul # short multiply 00196 _ ; 00197 ssinc # store sixteen and increment 00198 _ ; 00199 statusclr # clear bits in status register 00200 _ ; 00201 statusset # set bits in status register 00202 _ ; 00203 statustst # test status register 00204 _ ; 00205 stl val # store local 00206 *32* m := %Areg 00207 POPALL(); 00208 stnl val # store non-local 00209 *32* m[%Areg + (val * 4) ] := %Breg 00210 POPALL() 00211 POPALL(); 00212 stop # stop process 00213 _ ; 00214 sub # subtract 00215 #OP2("-"); 00216 *32* %Areg := %Breg - %Areg 00217 POP1(); 00218 subc # subtract with carry 00219 _ ; 00220 swap32 # byte swap 32 00221 _ ; 00222 swinc # store word and increment 00223 _ ; 00224 timeslice # timeslice 00225 _ ; 00226 umac # unsigned multiply accumulate 00227 _ ; 00228 unsign # unsign argument 00229 _ ; 00230 wait # wait 00231 _ ; 00232 wsub # word subscript 00233 #OP2("*4 +"); 00234 *32* %Areg := (%Breg * 4) + %Areg 00235 POP1(); 00236 xbword # sign extend byte to word 00237 *32* %Areg := sgnex(8,32,%Areg{8}); 00238 xor # exclusive or 00239 #OP2("^"); 00240 *32* %Areg := %Breg ^ %Areg 00241 POP1(); 00242 00243 xsword # sign extend sixteen to word 00244 *32* %Areg := sgnex(16, 32, %Areg{16}); 00245 00246 # C2-C4 instructions 00247 00248 altq # alt start 00249 _ ; 00250 altend # alt end 00251 _ ; 00252 altwt # alt wait 00253 _ ; 00254 bcnt # byte count 00255 *32* %Areg := %Areg * 32; 00256 bitcnt # count bits set in word 00257 _ ; 00258 bitrevnbits # reverse bottom n bits in word 00259 _ ; 00260 bitrevword # reverse bits in word 00261 _ ; 00262 bsub # byte subscript 00263 #OP2("+"); 00264 *32* %Areg := %Breg + %Areg 00265 POP1(); 00266 call val # call 00267 *32* %sp := %sp - 16 00268 *32* m[%sp] := %pc 00269 *32* m[%sp+4] := %Areg 00270 *32* m[%sp+8] := %Breg 00271 *32* m[%sp+12] := %Creg 00272 # *32* %Areg := %pc 00273 # *32* %Breg := -1 00274 # *32* %Creg := -1 00275 *32* %pc := %pc + val; 00276 # *32* %pc := val; 00277 call1 val # call 00278 *32* %sp := %sp - 16 00279 *32* m[%sp] := %pc 00280 *32* m[%sp+4] := %Areg 00281 *32* m[%sp+8] := %Breg 00282 *32* m[%sp+12] := %Creg; 00283 # *32* %Areg := %pc 00284 # *32* %Breg := -1 00285 # *32* %Creg := -1 00286 # *32* %pc := %pc + val; 00287 # *32* %pc := val; 00288 call2 val # call 00289 *32* %sp := %sp - 16 00290 *32* m[%sp] := %pc 00291 *32* m[%sp+4] := %Areg 00292 *32* m[%sp+8] := %Breg 00293 *32* m[%sp+12] := %Creg 00294 *32* %sp := %sp + 16; 00295 # *32* %Areg := %pc 00296 # *32* %Breg := -1 00297 # *32* %Creg := -1 00298 # *32* %pc := %pc + val; 00299 # *32* %pc := val; 00300 causeerror # cause error 00301 _ ; 00302 cb # check byte 00303 _ ; 00304 cbu # check byte unsigned 00305 _ ; 00306 ccnt1 # check count from 1 00307 _ ; 00308 cflerr # check floating point error 00309 _ ; 00310 cir # check in range 00311 _ ; 00312 ciru # check in range unsigned 00313 _ ; 00314 clockdis # clock disable 00315 _ ; 00316 clockenb # clock enable 00317 _ ; 00318 clrhalterr # clear halt-on error flag 00319 _ ; 00320 crcbyte # calculate CRC on byte 00321 _ ; 00322 crcword # calculate CRC on word 00323 _ ; 00324 cs # check sixteen 00325 _ ; 00326 csngl # check single 00327 _ ; 00328 csu # check sixteen unsigned 00329 _ ; 00330 csub0 # check subscript from 0 00331 _ ; 00332 cword # check word 00333 _ ; 00334 devlb # device load byte 00335 *32* %Areg := zfill(8,32,m[%Areg]{8}); 00336 devls # device load sixteen 00337 *32* %Areg := zfill(16,32,m[%Areg]{16}); 00338 devlw # device load word 00339 *32* %Areg := m{32}; 00340 devmove # device move 00341 _ ; 00342 devsb # device store byte 00343 *8* m := %Breg 00344 POPALL() 00345 POPALL(); 00346 devss # device store sixteen 00347 *16* m := %Breg 00348 POPALL() 00349 POPALL(); 00350 devsw # device store word 00351 *32* m := %Breg 00352 POPALL() 00353 POPALL(); 00354 diff # difference 00355 #OP2("-"); 00356 *32* %Areg := %Breg - %Areg 00357 POP1(); 00358 disc # disable channel 00359 _ ; 00360 diss # disable skip 00361 _ ; 00362 dist # disable timer 00363 _ ; 00364 div # divide 00365 #OP2("/"); 00366 *32* %Areg := %Breg / %Areg 00367 POP1(); 00368 enbc # enable channel 00369 _ ; 00370 enbs # enable skip 00371 _ ; 00372 enbt # enable timer 00373 _ ; 00374 endp # end process 00375 _ ; 00376 fmul # fractional multiply 00377 _ ; 00378 fptesterr # test for FPU error 00379 _ ; 00380 gcall # general call 00381 *32* tmp := %pc 00382 *32* %pc := %Areg 00383 *32* %Areg := tmp; 00384 gintdis # general interrupt disable 00385 _ ; 00386 gintenb # general interrupt enable 00387 _ ; 00388 in # input message 00389 _ ; 00390 insertqueue # insert at front of scheduler queue 00391 _ ; 00392 intdis # (localised) interrupt disable 00393 _ ; 00394 intenb # (localised) interrupt enable 00395 _ ; 00396 iret # interrupt return 00397 *32* %Creg := m{32} 00398 *32* %Breg := m{32} 00399 *32* %Areg := m{32} 00400 *32* %pc := m{32} 00401 *32* %sp := m{32}; 00402 # no status reg yet 00403 ladd # long add 00404 *32* %Areg := %Areg + %Breg + zfill(1,32,%Creg@[0:0]) 00405 POP2(); 00406 lb # load byte 00407 *32* %Areg := m{8}; 00408 lbx # load byte and sign extend 00409 *32* %Areg := m{8}; 00410 ldclock # load clock 00411 _ ; 00412 lddevid # load device identity 00413 _ ; 00414 ldiff # long diff 00415 *33* tmp := %Breg - %Areg - zfill(1,32,%Creg@[0:0]) 00416 *32* %Areg := tmp@[0:31] 00417 *32* %Breg := tmp@[32:32] 00418 *32* %Creg := -1; 00419 ldinf # load infinity 00420 PUSH(INF); 00421 ldiv # long divide 00422 *64* tmp@ := %Breg 00423 *64* tmp@ := %Creg 00424 *32* %Breg := tmp % %Areg 00425 *32* %Areg := tmp / %Areg 00426 *32* %Creg := -1; 00427 ldmemstartval # load value of MemStart address 00428 _ ; 00429 ldpri # load current priority 00430 _ ; 00431 ldshadow # load shadow registers 00432 _ ; 00433 ldtimer # load timer 00434 PUSH(0); 00435 ldtraph # load trap handler 00436 _ ; 00437 ldtrapped # load trapped process status 00438 _ ; 00439 lend # loop end 00440 _ ; 00441 lmul # long multiply 00442 *64* tmp := %Breg * %Areg 00443 *32* %Areg := tmp@ 00444 *32* %Breg := tmp@ 00445 *32* %Creg := -1; 00446 ls # load sixteen 00447 *32* %Areg := m{16}; 00448 lshl # long shift left 00449 #OP2("<<"); 00450 *32* %Areg := %Breg >> %Areg 00451 POP1(); 00452 lshr # long shift right 00453 #OP2(">>"); 00454 *32* %Areg := %Breg >> %Areg 00455 POP1(); 00456 lsub # long subtract 00457 _ ; 00458 lsum # long sum 00459 _ ; 00460 lsx # load sixteen and sign extend 00461 *32* %Areg := m{16}; 00462 mint # minimum integer 00463 PUSH(SIGN_32_NEG); 00464 move # move message 00465 _ ; #special function 00466 move2dall # 2D block copy 00467 _ ; 00468 move2dinit # initialize data for 2D block move 00469 _ ; 00470 move2dnonzero # 2D block copy non-zero bytes 00471 _ ; 00472 move2dzero # 2D block copy zero bytes 00473 _ ; 00474 norm # normalize 00475 _ ; 00476 out # output message 00477 _ ; 00478 outbyte # output byte 00479 _ ; 00480 outword # output word 00481 _ ; 00482 pop # pop processor stack 00483 POPALL(); 00484 postnormsn # post-normalize correction of single length fp number 00485 _ ; 00486 prod # product 00487 #OP2("*"); 00488 *32* %Areg := %Breg * %Areg 00489 POP1(); 00490 reboot # reboot 00491 _ ; 00492 rem # remainder 00493 #OP2("%"); 00494 *32* %Areg := %Breg % %Areg 00495 POP1(); 00496 resetch # reset channel 00497 _ ; 00498 restart # restart 00499 _ ; 00500 ret # return 00501 *32* %pc := m{32} 00502 *32* %sp := %sp + 16; 00503 roundsn # round single length floating point number 00504 _ ; 00505 runp # run process 00506 _ ; 00507 satadd # saturating add 00508 _ ; 00509 satmul # saturating multiply 00510 _ ; 00511 satsub # saturating subtract 00512 _ ; 00513 saveh # save high priority queue registers 00514 _ ; 00515 savel # save low priority queue registers 00516 _ ; 00517 sb # store byte 00518 *8* m := %Breg@ 00519 POP2(); 00520 seterr # set error flags 00521 _ ; 00522 sethalterr # set halt-on error flag 00523 _ ; 00524 settimeslice # set timeslicing status 00525 _ ; 00526 slmul # signed long multiply 00527 _ ; 00528 ss # store sixteen 00529 *16* m := %Breg@ 00530 POP2(); 00531 ssub # sixteen subscript 00532 #OP2("*2 +"); 00533 *32* %Areg := (%Breg *2) + %Areg 00534 POP1(); 00535 startp # start process 00536 _ ; 00537 stclock # store clock register 00538 _ ; 00539 sthb # store high priority back pointer 00540 _ ; 00541 sthf # store high priority front pointer 00542 _ ; 00543 stlb # store low priority back pointer 00544 _ ; 00545 stlf # store low priority front pointer 00546 _ ; 00547 stoperr # stop on error 00548 _ ; 00549 stopp # stop process 00550 _ ; 00551 stshadow # store shadow registers 00552 _ ; 00553 sttimer # store timer 00554 _ ; 00555 sttraph # store trap handler 00556 _ ; 00557 sttrapped # store trapped process 00558 _ ; 00559 sulmul # signed timer unsigned long multiply 00560 _ ; 00561 sum # sum 00562 _ ; 00563 swapqueue # swap scheduler queue 00564 _ ; 00565 swaptimer # swap timer queue 00566 _ ; 00567 talt # timer alt start 00568 _ ; 00569 taltwt # timer alt wait 00570 _ ; 00571 testerr # test error flag 00572 _ ; 00573 testhalterr # test halt-on error flag 00574 _ ; 00575 testpranal # test processor analysing 00576 _ ; 00577 tin # timer input 00578 _ ; 00579 trapdis # trap disable 00580 _ ; 00581 trapenb # trap enable 00582 _ ; 00583 tret # trap return 00584 _ ; 00585 unpacksn # unpack single length fp number 00586 _ ; 00587 wcnt # word count 00588 _ ; 00589 wsubdb # form double word subscript 00590 #OP2("*8 +"); 00591 *32* %Areg := (%Breg *8) + %Areg 00592 POP1(); 00593 xdble # extend to double 00594 *32* %Creg := %Breg 00595 *32* %Breg := ; 00596 xword # extend word 00597 _ ;