Shop OBEX P1 Docs P2 Docs Learn Events
PNut/Spin2 Latest Version (v47 - Cooperative multitasking added to Spin2, up to 32 tasks) - Page 36 — Parallax Forums

PNut/Spin2 Latest Version (v47 - Cooperative multitasking added to Spin2, up to 32 tasks)

1333436383970

Comments

  • TonyB_TonyB_ Posts: 2,190
    edited 2020-11-21 13:23
    deleted
  • Here are the three other non-trivial code blocks requiring STALLI/ALLOWI to REP changes:
    ' Write bitfield			(12 longs, must be in regs)
    '
    wrf		mov	fd,x		'get bitfield data
    		rol	fd,fb
    
    		bmask	fm,sz		'make bitfield mask
    		rol	fm,fb
    
    		mov	fx,x		'preserve x
    		stalli			'protect variable
    wrf_rd		push	#$1FF		'read variable into x (rewritten)	(initially: push $1FF, to begin xbyte on _ret_)
    		setq	fm		'set bitfield mask			(initially: no consequence)
    		muxq	x,fd		'mux bitfield data into x		(initially: no consequence)
    wrf_wr	_ret_	setq	#$0A1		'write x back to variable (rewritten)	(initially: begin xbyte, compress Ax..Fx, write flags)
    		allowi			'unprotect variable
    	_ret_	mov	x,fx		'restore x
    
    ' Variable assignments / math operators	(85 longs)
    '
    una_iso		mov	w,x		'	m				a: !!
    una_psh		pusha	x		'push	| n				b: !			
    		alti	rd		'rd	m n				c: - (neg)
    op_notb		test	x	wz	'rd,!!	m n a				d: ABS
    op_quna		stalli			'	x x |               i j k	e: ENCOD
    		qsqrt	x,#0		'SQRT	x x |               i | |	f: DECOD
    		qlog	x		'LOG	x x |               | j |	g: BMASK
    		qexp	x		'EXP	x x |               | | k	h: ONES
    		muxz	x,_FFFFFFFF	'!!	x x a               | | |	i: SQRT
    op_not		not	x		'!	x x | b             | | |	j: LOG
    op_neg		neg	x		'-	x x | | c           | | |	k: EXP
    op_abs		abs	x		'ABS	x x | | | d         | | |
    op_encod	encod	x		'ENCOD	x x | | | | e       | | |
    op_decod	decod	x		'DECOD	x x | | | | | f     | | |
    op_bmask	bmask	x		'BMASK	x x | | | | | | g   | | |
    op_ones		ones	x		'ONES	x x | | | | | | | h | | |
    		getqx	x		'	x x | | | | | | | | i j k
    		allowi			'	x x | | | | | | | | i j k
    		alti	wr		'wr	m n | | | | | | | | | | |
    		ret			'wr,op	m n a b c d e f g h i j k	m: ?= var	(isolated)
    	_ret_	mov	x,w		'iso	m |				n: ?= var	(push)
    	_ret_	zerox	x,sz		'push	  n				x: use a..j
    
    mul_mod		abs	w,x	wc	'C=ys	x x   b   d     g		a: *
    muu_mod		mov	w,x		'	x x a | c | e f | h		b: /
    		alti	rd		'rd	m n | | | | | | | |		c: +/
    		popa	x		'rd,op	m n a b c d e f g h		d: //
    		testb	x,#31	wz	'Z=xs	x x | b | d | | g |		e: +//
    		abs	x		'	x x | b | d | | g |		f: SCA
    		stalli			'	x x a b c d e f g h		g: SCAS
    		qmul	x,w		'*,SCAx	x x a | | | | f g |		h: FRAC
    		qdiv	x,w		'/,//	x x | b c d e | | |
    		qfrac	x,w		'FRAC	x x | | | | | | | h
    		getqx	x		'	x x a b c | | | | h
        if_c_ne_z	neg	x		'*,/	x x | b | | | | | |
    		getqy	x		'	x x | | | d e f g |
        if_z	neg	x		'//	x x | | | d | | | |
    		call	#\.scas		'SCAS	x x | | | | | | g |
    		allowi			'	x x a b c d e f g h
    		alti	wr		'wr	m n | | | | | | | |
    		ret			'wr,op	m n a b c d e f g h		m: var ?= exp	(isolated)
    	_ret_	popa	x		'iso	m |				n: var ?= exp	(push)
    	_ret_	zerox	x,sz		'push	  n				x: use a..h
    
  • evanhevanh Posts: 16,014
    TonyB_ wrote: »
    For the _RET_ to take effect, it appears that the repeat instruction count has to be one more than the number of instructions executed in the REP block.
    As per the examples of using REP, the ".end" label is meant to be placed after the last instruction of the REP block.
  • That 3rd case that TonyB_ posted above with the extra "neg x" (b,d paths) looks tricky to solve with a REP as the instruction counts will differ. It would need rearrangement somehow to bring the counts to the same length.

    Depending on what the m,n,x cases need to do you might be able to move this line to follow the GETQY after which you could have interrupts enabled. That could possibly get the REP counts the same for the CORDIC part.
        if_c_ne_z	neg	x		'*,/	x x | b | | | | | |
    
  • evanhevanh Posts: 16,014
    edited 2020-11-20 23:01
    No, in these cases REP isn't intended for looping. The specified REP length just has to be longer is all. May as well be REP #511, #1. The final RET branch cancels the REP mechanism, restoring IRQ handling.

  • Yeah ok, that's right, it's not looping and that ret branch there should save us when it cancels the REP. In general this REP+SKIPF stuff does need careful thought as to where it works and it can be tricky. I know I've been caught there before in my video driver work.
  • TonyB_TonyB_ Posts: 2,190
    edited 2020-11-21 11:10
    deleted
  • evanhevanh Posts: 16,014
    edited 2020-11-21 00:19
    A label is safe. What I was concerned about was acceptable norm of using an exact number for looping. Or in this case, trying to be exact even though it isn't looping.

  • TonyB_TonyB_ Posts: 2,190
    edited 2020-11-21 11:09
    deleted
  • evanhevanh Posts: 16,014
    Your example placed it before the final instruction.
  • cgraceycgracey Posts: 14,202
    edited 2020-11-21 05:03
    Thanks for all these REP ideas. I was able to get rid of all ALLOWI instructions by substituting REP for STALLI. This saved 14 instructions in the interpreter, which is pretty significant. It freed up 4 longs in cog register space and 10 longs in hub space.

    Here is the most complicated usage or REP to shield CORDIC operations from interrupts. I used #99 just to cover every case and imply infinity. The interrupt protection ends when the call/ret/_ret_ execute, which is fine:
    mul_mod		abs	w,x	wc	'C=ys	x x   b   d     g		a: *
    muu_mod		mov	w,x		'	x x a | c | e f | h		b: /
    		alti	rd		'rd	m n | | | | | | | |		c: +/
    		popa	x		'rd,op	m n a b c d e f g h		d: //
    		testb	x,#31	wz	'Z=xs	x x | b | d | | g |		e: +//
    		abs	x		'	x x | b | d | | g |		f: SCA
    		rep	#99,#1		'	x x a b c d e f g h		g: SCAS		use REP to protect cordic operation until call/ret/_ret_
    		qmul	x,w		'*,SCAx	x x a | | | | f g |		h: FRAC
    		qdiv	x,w		'/,//	x x | b c d e | | |
    		qfrac	x,w		'FRAC	x x | | | | | | | h
    		getqx	x		'	x x a b c | | | | h
        if_c_ne_z	neg	x		'*,/	x x | b | | | | | |
    		getqy	x		'	x x | | | d e f g |
        if_z	neg	x		'//	x x | | | d | | | |
    		getqx	w		'SCAS	x x | | | | | | g |
    		call	#\.scas		'SCAS	x x | | | | | | g |
    		alti	wr		'wr	m n | | | | | | | |
    		ret			'wr,op	m n a b c d e f g h		m: var ?= exp	(isolated)
    	_ret_	popa	x		'iso	m |				n: var ?= exp	(push)
    	_ret_	zerox	x,sz		'push	  n				x: use a..h
    
    .scas if_c_eq_z	jmp	#.scas2		'adjust 64-bit product for SCAS
    		neg	w	wz	'conditionally negate {x,w}
        if_nz	not	x
        if_z	neg	x
    .scas2		shl	x,#2		'x = {x,w}[61:30]
    		shr	w,#32-2
    	_ret_	or	x,w
    

    Here is the new interpreter with these changes.

  • Cluso99Cluso99 Posts: 18,069
    edited 2020-11-21 05:32
    Presume we just need to copy to the pnut35 directory and replace the old one ;)

    This trick needs to go into the P2 Tricks and Traps Reference thread.
  • cgraceycgracey Posts: 14,202
    I posted a new v35a, in which the interpreter has been shrunk by 14 longs by using REP as an interrupt shield, instead of STALLI+ALLOWI.

    There's a very slight performance increase, but I'm mainly wanting to put it out now, in case anyone notices a problem with it. Seems to work fine for me. I'm extremely careful when I make these kinds of edits, because things can go sideways in unexpected ways. Just interested to see if anybody has a problem with it.
  • Cluso99Cluso99 Posts: 18,069
    cgracey wrote: »
    I posted a new v35a, in which the interpreter has been shrunk by 14 longs by using REP as an interrupt shield, instead of STALLI+ALLOWI.

    There's a very slight performance increase, but I'm mainly wanting to put it out now, in case anyone notices a problem with it. Seems to work fine for me. I'm extremely careful when I make these kinds of edits, because things can go sideways in unexpected ways. Just interested to see if anybody has a problem with it.
    So what are you going to squeeze into this new found space :sunglasses:
  • cgraceycgracey Posts: 14,202
    Cluso99 wrote: »
    cgracey wrote: »
    I posted a new v35a, in which the interpreter has been shrunk by 14 longs by using REP as an interrupt shield, instead of STALLI+ALLOWI.

    There's a very slight performance increase, but I'm mainly wanting to put it out now, in case anyone notices a problem with it. Seems to work fine for me. I'm extremely careful when I make these kinds of edits, because things can go sideways in unexpected ways. Just interested to see if anybody has a problem with it.
    So what are you going to squeeze into this new found space :sunglasses:

    Nothing, at this point. Just good to conserve where you can, because we'll need it in the future.
  • TonyB_TonyB_ Posts: 2,190
    edited 2020-11-21 17:11
    Could more use be made of _ret_ to avoid a separate ret?

    ALTI D is an interesting instruction. Just wondering whether a _RET_ prefix will do a RET after D replaces next instruction.

    EDIT:
    Duff code deleted
  • cgraceycgracey Posts: 14,202
    edited 2020-11-21 14:37
    "_ret_ altd" would affect the next instruction in the pipeline, but that next instruction would get cancelled due to the _ret_.

    We could do "_ret_ neg x", for those unary cases which don't write back to the variable, but it would take an extra instruction for each case. By using a discrete ret after, we can get all three use cases out of "neg x".
  • cgraceycgracey Posts: 14,202
    I finally got the DEBUG MIDI display documented. I think the Spin2 doc is completely up-to-date now.
  • The document still says 34u.

    Mike
  • cgraceycgracey Posts: 14,202
    iseries wrote: »
    The document still says 34u.

    Mike

    Thanks. I just fixed it.
  • TonyB_TonyB_ Posts: 2,190
    edited 2020-11-22 11:07
    The doc says this in a couple of places:
    Spin2 accommodates interrupts and only stalls them briefly, when necessary.
    The word "stalls" suggests that STALLI is used, which is not the case now. I suggest the following:
    Spin2 accommodates interrupts and only blocks them briefly, when necessary.
    or
    Spin2 accommodates interrupts and only blocks them briefly, when necessary, and does not use either STALLI or ALLOWI.
  • cgraceycgracey Posts: 14,202
    TonyB_ wrote: »
    The doc says this in a couple of places:
    Spin2 accommodates interrupts and only stalls them briefly, when necessary.
    The word "stalls" suggests that STALLI is used, which is not the case now. I suggest the following:
    Spin2 accommodates interrupts and only blocks them briefly, when necessary.
    or
    Spin2 accommodates interrupts and only blocks them briefly, when necessary, and does not use either STALLI or ALLOWI.

    Okay. Will do. Thanks, TonyB_
  • evanhevanh Posts: 16,014
    edited 2020-11-22 20:30
    Stall is still okay term to use. I remember that "stall" was a carefully chosen term to confer a pending effect rather than erasing of.

  • maybe
    Spin2 accommodates interrupts and only delays them briefly, when necessary
  • cgraceycgracey Posts: 14,202
    Wuerfel_21 wrote: »
    maybe
    Spin2 accommodates interrupts and only delays them briefly, when necessary

    Maybe? Now I'm worried. What do you mean?
  • cgracey wrote: »
    Wuerfel_21 wrote: »
    maybe
    Spin2 accommodates interrupts and only delays them briefly, when necessary

    Maybe? Now I'm worried. What do you mean?

    Just suggesting an alternative wording that doesn't involve the word "stall" but still conveys that the interrupt will fire eventually.
  • evanhevanh Posts: 16,014
    Ah, heh, right, maybe use the term "delay" ...
  • Cluso99Cluso99 Posts: 18,069
    Suspend?
  • How about "blocks"?
  • evanhevanh Posts: 16,014
    Suspend and block both confer a cancelling rather than pending effect.

Sign In or Register to comment.