/[dtapublic]/to_be_filed/uculib01/src/stm8/cosmic/modx0/ats32s16v2cprxx/src/ats32s16v2cprxx.s
ViewVC logotype

Contents of /to_be_filed/uculib01/src/stm8/cosmic/modx0/ats32s16v2cprxx/src/ats32s16v2cprxx.s

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations) (download)
Sat Oct 8 07:22:17 2016 UTC (7 years, 11 months ago) by dashley
File size: 22246 byte(s)
Initial commit.
1 ;-------------------------------------------------------------------------------
2 ;$Header: /home/dashley/cvsrep/uculib01/uculib01/src/stm8/cosmic/modx0/ats32s16v2cprxx/src/ats32s16v2cprxx.s,v 1.5 2010/04/16 21:22:27 dashley Exp $
3 ;-------------------------------------------------------------------------------
4 ;Copyright (c)2010 David T. Ashley
5 ;
6 ;Permission is hereby granted, free of charge, to any person obtaining a copy
7 ;of this software source code and associated documentation files (the
8 ;"Software"), to deal in the Software without restriction, including without
9 ;limitation the rights to use, copy, modify, merge, publish, distribute,
10 ;sublicense, and/or sell copies of the Software, and to permit persons to whom
11 ;the Software is furnished to do so, subject to the following conditions:
12 ;
13 ;The above copyright notice and this permission notice shall be included in
14 ;all copies or substantial portions of the Software.
15 ;
16 ;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 ;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 ;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 ;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 ;THE SOFTWARE.
23 ;-------------------------------------------------------------------------------
24 ;This function doesn't use any static storage, so it is OK for either mods0 or
25 ;modsl0 memory models. However, it does assume call/ret (rather than callf/retf)
26 ;which affects both instructions used, stack offsets, and numerical values in
27 ;the .dcall directive. For this reason, must error out if being assembled
28 ;for the wrong memory model.
29 #ifndef UCU_BD_MMBP
30 #error "Program memory model define not provided on command line (UCU_BD_MMBP)."
31 #endif
32 #if (UCU_BD_MMBP != 1)
33 #error "Attempt to assemble module for wrong program memory model (UCU_BD_MMBP != 1)."
34 #endif
35 ;
36 xref.b c_lreg ;We use this for the return value.
37 ;
38 switch .text
39 xdef _UcuAtS32S16v2CpRxx
40 ;
41 ;Per discussion with Cosmic, the first integer is the stack space used by the
42 ;call instruction plus any automatic storage used by the function. The second integer
43 ;is the number of bytes stacked by the caller. Haven't yet discussed the scenario
44 ;of one assembly-language function called by another. I've noticed that some
45 ;assembly-language functions have a larger first integer than the stack they
46 ;used, so there may be a special convention if C calls .S which then calls .S,
47 ;as maybe the tools don't detect the .S calling the .S. Will need to investigate
48 ;further with Cosmic.
49 ;
50 ;2 bytes pushed on the stack by the call, 11 bytes stacked locally. 6 bytes
51 ;stacked by caller.
52 .dcall "13,6,_UcuAtS32S16v2CpRxx"
53 ;
54 _UcuAtS32S16v2CpRxx:
55 ;********************************************************************************
56 ;********************************************************************************
57 ;***** S T A C K F R A M E S E T U P ************************************
58 ;********************************************************************************
59 ;********************************************************************************
60 ;X contains a_x, and the other parameters are on the stack
61 ;already.
62 ;
63 ;Stack frame now:
64 ; ( 1,SP) : Return address MSB.
65 ; ( 2,SP) : Return address LSB.
66 ; ( 3,SP) : a_y MSB.
67 ; ( 4,SP) : a_y LSB.
68 ; ( 5,SP) : b_x MSB.
69 ; ( 6,SP) : b_x LSB.
70 ; ( 7,SP) : b_y MSB.
71 ; ( 8,SP) : b_y LSB.
72 ;----------
73 ;Push the X register onto the stack so we won't lose it.
74 pushw x
75 ;Stack frame now:
76 ; ( 1,SP) : a_x MSB.
77 ; ( 2,SP) : a_x LSB.
78 ; ( 3,SP) : Return address MSB.
79 ; ( 4,SP) : Return address LSB.
80 ; ( 5,SP) : a_y MSB.
81 ; ( 6,SP) : a_y LSB.
82 ; ( 7,SP) : b_x MSB.
83 ; ( 8,SP) : b_x LSB.
84 ; ( 9,SP) : b_y MSB.
85 ; (10,SP) : b_y LSB.
86 ;----------
87 ;Claim 9 additional bytes on the stack.
88 subw sp,#9
89 ;Stack frame now:
90 ; ( 1,SP) : Bit-packed status byte, used to remember signs of products and special cases.
91 ; Bit 7 -- 128 -- a_x * b_y is negative.
92 ; Bit 6 -- 64 -- a_y * b_x is negative.
93 ; Bit 5 -- 32 -- a_x is -32768.
94 ; Bit 4 -- 16 -- a_y is -32768.
95 ; Bit 3 -- 8 -- b_x is -32768.
96 ; Bit 2 -- 4 -- b_y is -32768.
97 ; ( 2,SP) : a_x * b_y, as a UCU_SINT32.
98 ; ( 3,SP) : ""
99 ; ( 4,SP) : ""
100 ; ( 5,SP) : ""
101 ; ( 6,SP) : -(a_y * b_x) as a UCU_SINT32.
102 ; ( 7,SP) : ""
103 ; ( 8,SP) : ""
104 ; ( 9,SP) : ""
105 ; (10,SP) : a_x MSB.
106 ; (11,SP) : a_x LSB.
107 ; (12,SP) : Return address MSB.
108 ; (13,SP) : Return address LSB.
109 ; (14,SP) : a_y MSB.
110 ; (15,SP) : a_y LSB.
111 ; (16,SP) : b_x MSB.
112 ; (17,SP) : b_x LSB.
113 ; (18,SP) : b_y MSB.
114 ; (19,SP) : b_y LSB.
115 ;
116 ;********************************************************************************
117 ;********************************************************************************
118 ;***** C O N V E R S I O N T O S I G N - M A G N I T U D E **************
119 ;********************************************************************************
120 ;********************************************************************************
121 ;----------
122 ;Clear the sign status byte.
123 clr (1,sp)
124 ;----------
125 ;Process the sign of a_x. This will record the sign and complement if negative to give
126 ;a sign-magnitude representation. a_x is still in the x register.
127 tnzw x
128 jrpl ax_is_nonnegative
129 ld a,(1,sp) ;Invert the a_x * b_y product neg bit.
130 xor a,#128
131 ld (1,sp),a
132 negw x ;This has the desirable side effect of setting the V bit
133 ;if the input (and output) are -32768.
134 ldw (10,sp),x ;Store the inverted result back.
135 jrnv ax_is_nonnegative
136 ld a,(1,sp) ;Set the a_x is -32768 bit.
137 or a,#32
138 ld (1,sp),a
139 ax_is_nonnegative:
140 ;----------
141 ;Process the sign of a_y. This will record the sign and complement if negative to give
142 ;a sign-magnitude representation.
143 ldw x,(14,sp)
144 tnzw x
145 jrpl ay_is_nonnegative
146 ld a,(1,sp) ;Invert the a_y * b_x product neg bit.
147 xor a,#64
148 ld (1,sp),a
149 negw x ;This has the desirable side effect of setting the V bit
150 ;if the input (and output) are -32768.
151 ldw (14,sp),x ;Store the inverted result back.
152 jrnv ay_is_nonnegative
153 ld a,(1,sp) ;Set the a_y is -32768 bit.
154 or a,#16
155 ld (1,sp),a
156 ay_is_nonnegative:
157 ;----------
158 ;Process the sign of b_x. This will record the sign and complement if negative to give
159 ;a sign-magnitude representation.
160 ldw x,(16,sp)
161 tnzw x
162 jrpl bx_is_nonnegative
163 ld a,(1,sp) ;Invert the a_y * b_x product neg bit.
164 xor a,#64
165 ld (1,sp),a
166 negw x ;This has the desirable side effect of setting the V bit
167 ;if the input (and output) are -32768.
168 ldw (16,sp),x ;Store the inverted result back.
169 jrnv bx_is_nonnegative
170 ld a,(1,sp) ;Set the a_x is -32768 bit.
171 or a,#8
172 ld (1,sp),a
173 bx_is_nonnegative:
174 ;----------
175 ;Process the sign of b_y. This will record the sign and complement if negative to give
176 ;a sign-magnitude representation.
177 ldw x,(18,sp)
178 tnzw x
179 jrpl by_is_nonnegative
180 ld a,(1,sp) ;Invert the a_x * b_y product neg bit.
181 xor a,#128
182 ld (1,sp),a
183 negw x ;This has the desirable side effect of setting the V bit
184 ;if the input (and output) are -32768.
185 ldw (18,sp),x ;Store the inverted result back.
186 jrnv by_is_nonnegative
187 ld a,(1,sp) ;Set the b_y is -32768 bit.
188 or a,#4
189 ld (1,sp),a
190 by_is_nonnegative:
191 ;********************************************************************************
192 ;********************************************************************************
193 ;***** A _ X * B _ Y C A L C U L A T I O N *************************
194 ;********************************************************************************
195 ;********************************************************************************
196 ;Form the product of a_x * b_y into (2,SP), (3,SP), (4,SP), and (5,SP).
197 ;There are special cases first.
198 ;
199 ;Look for a_x = b_y = -32768
200 ld a,(1,sp) ;Grab the status byte.
201 and a,#36
202 jreq ax_by_neither_negmax ;Branch around in the most typical case, which is that neither
203 ;a_x nor b_y is -32768.
204 cp a,#36
205 jrne ax_by_not_both_negmax
206 ;----------
207 ;If we are here, a_x and b_y were both -32768. The product in this case
208 ;is 2^30.
209 ldw x,#16384
210 ldw (2,sp),x
211 clrw x
212 ldw (4,sp),x
213 jra ax_by_done
214 ;----------
215 ;If we are here, either a_x = -32768 or b_y = -32768, but not both.
216 ;
217 ax_by_not_both_negmax:
218 cp a,#4
219 jreq by_is_negmax
220 ;----------
221 ;If we are here here, a_x = -32768, but b_y is another value.
222 ;Multiplication by 32768 is equivalent to left-shifting by 15 places. The approach
223 ;used is to left-shift by 16 places, then to back off 1 by right-shifting once.
224 ;
225 ldw x,(18,sp)
226 sraw x
227 clrw y
228 jrnc ax_is_negmax_01
229 ldw y,#32768
230 ax_is_negmax_01:
231 ;
232 ;X and Y are loaded with the unsigned product now. Need to negate if the
233 ;ax * by neg bit is set.
234 ld a,(1,sp)
235 and a,#128
236 jreq ax_is_negmax_nonegate
237 cplw x
238 cplw y
239 incw y
240 jrne ax_is_negmax_nonegate
241 incw x ;Incrementing Y (the LSW) generated a carry into X (the MSW).
242 ax_is_negmax_nonegate:
243 ldw (2,sp),x
244 ldw (4,sp),y
245 jra ax_by_done ;We are done with calculating the ax * by term.
246
247 ;----------
248 by_is_negmax:
249 ;If we are here, b_y = -32768, but a_x is another value.
250 ;Multiplication by 32768 is equivalent to left-shifting by 15 places. The approach
251 ;used is to left-shift by 16 places, then to back off 1 by right-shifting once.
252 ;
253 ldw x,(10,sp)
254 sraw x
255 clrw y
256 jrnc by_is_negmax_01
257 ldw y,#32768
258 by_is_negmax_01:
259 ;
260 ;X and Y are loaded with the unsigned product now. Need to negate if the
261 ;ax * by neg bit is set.
262 ld a,(1,sp)
263 and a,#128
264 jreq by_is_negmax_nonegate
265 cplw x
266 cplw y
267 incw y
268 jrne by_is_negmax_nonegate
269 incw x ;Incrementing Y (the LSW) generated a carry into X (the MSW).
270 by_is_negmax_nonegate:
271 ldw (2,sp),x
272 ldw (4,sp),y
273 jra ax_by_done ;We are done with calculating the ax * by term.
274 ;----------
275 ax_by_neither_negmax:
276 ;If we are here, neither a_x nor b_y are at the negative limit. This is a simple
277 ;multiplication with optional negation.
278 ;
279 ;Clear most significant word of result in preparation for multiplication.
280 clrw x
281 ldw (2,sp),x
282 ;
283 ;a_x(0) * b_y(0)
284 ld a,(11,sp) ;a_x(0)
285 ld xl,a
286 ld a,(19,sp) ;b_y(0)
287 mul x,a
288 ldw (4,sp),x ;Store result.
289 ;
290 ;a_x(0) * b_y(1)
291 ld a,(11,sp) ;a_x(0)
292 ld xl,a
293 ld a,(18,sp) ;b_y(1)
294 mul x,a
295 addw x,(3,sp) ;Add in term. Note that carry isn't possible on this first
296 ;addition.
297 ldw (3,sp),x ;Store result.
298 ;
299 ;a_x(1) * b_y(0)
300 ld a,(10,sp) ;a_x(1)
301 ld xl,a
302 ld a,(19,sp) ;b_y(0)
303 mul x,a
304 addw x,(3,sp) ;Add in term. Carry is possible.
305 ldw (3,sp),x ;Store result.
306 jrnc ax_by_neither_negmax_nc
307 inc (2,sp) ;Propagate carry
308 ax_by_neither_negmax_nc:
309 ;
310 ;a_x(1) * b_y(1)
311 ld a,(10,sp) ;a_x(1)
312 ld xl,a
313 ld a,(18,sp) ;b_y(1)
314 mul x,a
315 addw x,(2,sp) ;Add in term. Carry is not possible.
316 ldw (2,sp),x ;Store result.
317 ;
318 ;Need to negate if the ax * by neg bit is set.
319 ld a,(1,sp)
320 and a,#128
321 jreq ax_by_done
322 ldw x,(2,sp)
323 ldw y,(4,sp)
324 cplw x
325 cplw y
326 incw y
327 jrne ax_by_neither_negmax_noinc
328 incw x ;Incrementing Y (the LSW) generated a carry into X (the MSW).
329 ax_by_neither_negmax_noinc:
330 ldw (2,sp),x
331 ldw (4,sp),y
332 ;----------
333 ax_by_done:
334 ;We are done with calculating a_x * b_y term.
335 ;----------
336 ;********************************************************************************
337 ;********************************************************************************
338 ;***** - ( A _ Y * B _ X ) C A L C U L A T I O N *******************
339 ;********************************************************************************
340 ;********************************************************************************
341 ;Form the product of a_y * b_x into (6,SP), (7,SP), (8,SP), and (9,SP).
342 ;There are special cases first.
343 ;
344 ;Look for a_y = b_x = -32768
345 ld a,(1,sp) ;Grab the status byte.
346 and a,#24
347 jreq ay_bx_neither_negmax ;Branch around in the most typical case, which is that neither
348 ;a_y nor b_x is -32768.
349 cp a,#24
350 jrne ay_bx_not_both_negmax
351 ;----------
352 ;If we are here, a_y and b_x were both -32768. The product in this case
353 ;is 2^30.
354 ldw x,#16384
355 ldw (6,sp),x
356 clrw x
357 ldw (8,sp),x
358 jra ay_bx_done
359 ;----------
360 ;If we are here, either a_y = -32768 or b_x = -32768, but not both.
361 ;
362 ay_bx_not_both_negmax:
363 cp a,#16
364 jreq bx_is_negmax
365 ;----------
366 ;If we are here here, a_y = -32768, but b_x is another value.
367 ;Multiplication by 32768 is equivalent to left-shifting by 15 places. The approach
368 ;used is to left-shift by 16 places, then to back off 1 by right-shifting once.
369 ;
370 ldw x,(16,sp)
371 sraw x
372 clrw y
373 jrnc ay_is_negmax_01
374 ldw y,#32768
375 ay_is_negmax_01:
376 ;
377 ;X and Y are loaded with the unsigned product now. Need to negate if the
378 ;ay * bx neg bit is NOT set. (The inverted logic is because we are forming
379 ;the negative product.)
380 ld a,(1,sp)
381 and a,#64
382 jrne ay_is_negmax_nonegate
383 cplw x
384 cplw y
385 incw y
386 jrne ay_is_negmax_nonegate
387 incw x ;Incrementing Y (the LSW) generated a carry into X (the MSW).
388 ay_is_negmax_nonegate:
389 ldw (6,sp),x
390 ldw (8,sp),y
391 jra ay_bx_done ;We are done with calculating the ay * bx term.
392
393 ;----------
394 bx_is_negmax:
395 ;If we are here, b_x = -32768, but a_y is another value.
396 ;Multiplication by 32768 is equivalent to left-shifting by 15 places. The approach
397 ;used is to left-shift by 16 places, then to back off 1 by right-shifting once.
398 ;
399 ldw x,(14,sp)
400 sraw x
401 clrw y
402 jrnc by_is_negmax_01
403 ldw y,#32768
404 bx_is_negmax_01:
405 ;
406 ;X and Y are loaded with the unsigned product now. Need to negate if the
407 ;ay * bx neg bit is NOT set.
408 ld a,(1,sp)
409 and a,#64
410 jrne bx_is_negmax_nonegate
411 cplw x
412 cplw y
413 incw y
414 jrne bx_is_negmax_nonegate
415 incw x ;Incrementing Y (the LSW) generated a carry into X (the MSW).
416 bx_is_negmax_nonegate:
417 ldw (6,sp),x
418 ldw (8,sp),y
419 jra ay_bx_done ;We are done with calculating the ay * bx term.
420 ;----------
421 ay_bx_neither_negmax:
422 ;If we are here, neither a_y nor b_x are at the negative limit. This is a simple
423 ;multiplication with optional negation.
424 ;
425 ;Clear most significant word of result in preparation for multiplication.
426 clrw x
427 ldw (6,sp),x
428 ;
429 ;a_y(0) * b_x(0)
430 ld a,(15,sp) ;a_y(0)
431 ld xl,a
432 ld a,(17,sp) ;b_x(0)
433 mul x,a
434 ldw (8,sp),x ;Store result.
435 ;
436 ;a_y(0) * b_x(1)
437 ld a,(15,sp) ;a_y(0)
438 ld xl,a
439 ld a,(16,sp) ;b_x(1)
440 mul x,a
441 addw x,(7,sp) ;Add in term. Note that carry isn't possible on this first
442 ;addition.
443 ldw (7,sp),x ;Store result.
444 ;
445 ;a_y(1) * b_x(0)
446 ld a,(14,sp) ;a_y(1)
447 ld xl,a
448 ld a,(17,sp) ;b_x(0)
449 mul x,a
450 addw x,(7,sp) ;Add in term. Carry is possible.
451 ldw (7,sp),x ;Store result.
452 jrnc ay_bx_neither_negmax_nc
453 inc (6,sp) ;Propagate carry
454 ay_bx_neither_negmax_nc:
455 ;
456 ;a_y(1) * b_x(1)
457 ld a,(14,sp) ;a_y(1)
458 ld xl,a
459 ld a,(16,sp) ;b_x(1)
460 mul x,a
461 addw x,(6,sp) ;Add in term. Carry is not possible.
462 ldw (6,sp),x ;Store result.
463 ;
464 ;Need to negate if the ay * bx neg bit is NOT set. (The inverted logic is because we are forming
465 ;the negative product.)
466 ld a,(1,sp)
467 and a,#64
468 jrne ay_bx_done
469 ldw x,(6,sp)
470 ldw y,(8,sp)
471 cplw x
472 cplw y
473 incw y
474 jrne ay_bx_neither_negmax_noinc
475 incw x ;Incrementing Y (the LSW) generated a carry into X (the MSW).
476 ay_bx_neither_negmax_noinc:
477 ldw (6,sp),x
478 ldw (8,sp),y
479 ;----------
480 ay_bx_done:
481 ;We are done with calculating -(a_x * b_y) term.
482 ;
483 ;*************************************************************************************
484 ;*************************************************************************************
485 ;***** T E R M A D D I T I O N , R E T U R N V A L U E S E T U P *****
486 ;*************************************************************************************
487 ;*************************************************************************************
488 ;Grab the two terms. Y is the LSW.
489 ldw x,(2,sp)
490 ldw y,(4,sp)
491 ;
492 ;Add the terms. Must propagate the carry.
493 addw y,(8,sp)
494 jrnc ta_rvs_nocarry
495 incw x
496 ta_rvs_nocarry:
497 addw x,(6,sp)
498 ;
499 ;Store the result in the location expected by the compiler.
500 ldw c_lreg,x
501 ldw c_lreg+2,y
502 ;
503 ;********************************************************************************
504 ;********************************************************************************
505 ;***** S T A C K C L E A N U P *******************************************
506 ;********************************************************************************
507 ;********************************************************************************
508 addw sp,#11 ;9 bytes explicitly allocated, plus 2 allocated via PUSHW X.
509 ;
510 ;********************************************************************************
511 ;********************************************************************************
512 ;***** F U N C T I O N R E T U R N ***************************************
513 ;********************************************************************************
514 ;********************************************************************************
515 ret
516 ;
517 end
518 ;
519 ;-------------------------------------------------------------------------------
520 ;End of $Id: ats32s16v2cprxx.s,v 1.5 2010/04/16 21:22:27 dashley Exp $
521 ;-------------------------------------------------------------------------------
522 ;$Log: ats32s16v2cprxx.s,v $
523 ;Revision 1.5 2010/04/16 21:22:27 dashley
524 ;Corrections.
525 ;
526 ;Revision 1.4 2010/04/14 21:41:57 dashley
527 ;Function complete, pending reviews and testing.
528 ;
529 ;Revision 1.3 2010/04/14 20:56:41 dashley
530 ;Edits.
531 ;
532 ;Revision 1.2 2010/04/14 20:10:18 dashley
533 ;Initial checkin.
534 ;
535 ;Revision 1.1 2010/04/14 20:09:53 dashley
536 ;Initial checkin.
537 ;-------------------------------------------------------------------------------
538

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25