flat assembler
Message board for the users of flat assembler.

Index > Programming Language Design > fasmg macro support for Parallax MCUs

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 20 Sep 2016, 21:11
I'm still getting used to what fasmg can do, in the macros.
Standard Opcodes I can find examples on, but there is a slight variant in Parallax MCUs that has me stalled ?

A simple ADD is easy enough

Code:
ADD ParD,ParS   ;100000 001i 1111 ddddddddd sssssssss    


but there is a skip form to every opcode, that encodes like

Code:
IF_Cond   ADD ParD,ParS   ;100000 001i wxyz ddddddddd sssssssss    


ie the Cond name, encodes into wxyz bits, with default/omitted taken as IF_ALWAYS -> 1111

What is a compact/efficient way to add such an optional prefix to fasmg ?
Post 20 Sep 2016, 21:11
View user's profile Send private message Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 20 Sep 2016, 23:19
jmg wrote:

A simple ADD is easy enough
Code:
ADD ParD,ParS   ;100000 001i 1111 ddddddddd sssssssss    



expanding on that, I find a small fasmg issue with binary numerics.

Code:
        dd (10000001b shl 22)
    

is accepted as ok, but a 10 char binary string gives an error ?
Code:
        dd (1000000010b shl 22)
    


Surely binary stings to 32 chars or even 64 should be valid ?
There may be a case for modula-8 length check, but in this case, the natural field is 10b, so that would make the macro larger than it needed to be.

Addit:
Just tested latest Version that adds Underscore, and it also fixed this issue.
(flat assembler g version 0.98.1474353977)

Valid now, are all of the below, a number too large for the field, flags an error.
Code:
        dd (10000000_10b shl 22)
        dd (1111_1010_0101_0111_0110_0101_0100_0011b)
;       dd (1_1111_1010_0101_0111_0110_0101_0100_0011b)   ; flags
        dq (1110_1111_1010_0101_0111_0110_0101_0100_0011_0010_0001b)
    

Looks very good.
Post 20 Sep 2016, 23:19
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 21 Sep 2016, 06:11
jmg wrote:
What is a compact/efficient way to add such an optional prefix to fasmg ?
A first thought that comes to my mind is to create IF_Cond instructions that would convert the condition to an additional argument at the end
Code:
iterate <Cond,wxyz>, TEST,1111b
        macro IF_#Cond? instruction& 
                instruction,wxyz 
        end macro 
end iterate

IF_TEST ADD ParD,ParS ; now becomes ADD ParD,ParS,1111b    

If you don't want to enable an optional syntax with additional parameter for instructions like ADD, you can also forward this to a variant of instruction in a special namespace, and handle additional parameter there:
Code:
define Conditioned ; create base symbol for namespace

iterate <Cond,wxyz>, TEST,1111b
        macro IF_#Cond? instruction&
                Conditioned.instruction,wxyz
        end macro 
end iterate

namespace Conditioned
        macro ADD? ParD,ParS,wxyz
                display `x
        end macro
end namespace

macro ADD? ParD,ParS    ; the regular instruction can now just forward processing
        Conditioned.ADD ParD,ParS,1111b
end macro    
Post 21 Sep 2016, 06:11
View user's profile Send private message Visit poster's website Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 21 Sep 2016, 06:57
Tomasz Grysztar wrote:
A first thought that comes to my mind is to create IF_Cond instructions that would convert the condition to an additional argument at the end


Thanks.

I tried the first form, and it gets very close with the result below

- it does not handle the default case of no IF_Test present.
ie the opcodes have the optional IF_Test prefix test.
In most cases, code does not use the IF_Test conditional
- in that case, a default of 1111b is applied to that part of the opcode.

Code:
macro pcADD? ParD,ParS,ParC
        dd (100000_0010b shl 22)+(ParC shl 18)+(ParD and 0x1ff) shl 9 + ParS and 0x1ff
end macro 

; guess this can generate 3+ opcodes, like...
iterate <Cond,wxyz>, TEST,1111b,TWO,0010b,THREE,0011b  
        macro IF_#Cond? instruction&  
                instruction,wxyz  
        end macro  
end iterate 

;  ~~~~~~~~~~ Test code ~~~~~~~~~~
IF_TEST  pcADD 0AH,05H    ; now becomes ADD ParD,ParS,1111b  OK
IF_TWO   pcADD 0AH,05H    ; now becomes ADD ParD,ParS,0010b OK
IF_THREE pcADD 0AH,05H    ; now becomes ADD ParD,ParS,0011b OK
;        pcADD 07H,03H    ; fails when no Cond prefix ?

    
Post 21 Sep 2016, 06:57
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 21 Sep 2016, 07:05
jmg wrote:
Code:
;  ~~~~~~~~~~ Test code ~~~~~~~~~~
IF_TEST  pcADD 0AH,05H    ; now becomes ADD ParD,ParS,1111b  OK
IF_TWO   pcADD 0AH,05H    ; now becomes ADD ParD,ParS,0010b OK
IF_THREE pcADD 0AH,05H    ; now becomes ADD ParD,ParS,0011b OK
;        pcADD 07H,03H    ; fails when no Cond prefix ?

    
In this case you could just do it like this:
Code:
macro pcADD? ParD*,ParS*,ParC:1111b 
        dd (100000_0010b shl 22)+(ParC shl 18)+(ParD and 0x1ff) shl 9 + ParS and 0x1ff 
end macro    
All arguments are normally optional (may have empty value), * marks the required arguments, and the third one has the default value.
Post 21 Sep 2016, 07:05
View user's profile Send private message Visit poster's website Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 21 Sep 2016, 07:15
Tomasz Grysztar wrote:
In this case you could just do it like this:
Code:
macro pcADD? ParD*,ParS*,ParC:1111b 
        dd (100000_0010b shl 22)+(ParC shl 18)+(ParD and 0x1ff) shl 9 + ParS and 0x1ff 
end macro    
All arguments are normally optional (may have empty value), * marks the required arguments, and the third one has the default value.


Cool, It did look close - this fasmg certainly is powerful Smile
Post 21 Sep 2016, 07:15
View user's profile Send private message Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 21 Sep 2016, 21:01
Progress Update : This structure seems to be working.
Takes ~2.2s to generate largest possible ASM image for Parallax P8X32A.

Code:
; Common Conditional, Dest, Source opcode parts 
; - can add range checks here ParD,ParS are simply masked here, and ParC is internally defined as always 4b
macro gpCDS? ParD*,ParS*,ParC:1111b   
 pCDS = (ParC shl 18)+(ParD and 0x1ff) shl 9 + ParS and 0x1ff
end macro

; Test a couple of P8X32A Opcodes, simpler forms.
; ADD 100000 001i cccc ddddddddd sssssssss
macro pcADD? ParD*,ParS*,ParC:1111b  
    gpCDS ParD,ParS,ParC
        match #data, ParS
          dd (100000_0011b shl 22) + pCDS
        else
          dd (100000_0010b shl 22) + pCDS
        end match
end macro 

; SUB 100001 001i cccc ddddddddd sssssssss
macro pcSUB? ParD*,ParS*,ParC:1111b  
    gpCDS ParD,ParS,ParC
        match #data, ParS
          dd (100001_0011b shl 22) + pCDS
        else  
          dd (100001_0010b shl 22) + pCDS
        end match  
end macro 

; ~~~~~~~ Generate all 32 IF_ forms ~~~~~~~~~~~~~~
; This expansion is done once, and then passes rest of line to another macro
iterate <Cond,wxyz>,\
ALWAYS,1111b,NEVER,0000b,E,1010b,NE,0101b,A,0001b,B,1100b,AE,0011b,BE,1110b,C,1100b,NC,0011b,\
Z,1010b,NZ,0101b,C_EQ_Z,1001b,C_NE_Z,0110b,C_AND_Z,1000b,C_AND_NZ,0100b,NC_AND_Z,0010b,NC_AND_NZ,0001b,\ 
C_OR_Z,1110b,C_OR_NZ,1101b,NC_OR_Z,1011b,NC_OR_NZ,0111b,Z_EQ_C,1001b,Z_NE_C,0110b,Z_AND_C,1000b,\  
Z_AND_NC,0010b,NZ_AND_C,0100b,NZ_AND_NC,0001b,Z_OR_C,1110b,Z_OR_NC,1011b,NZ_OR_C,1101b,NZ_OR_NC,0111b  
        macro IF_#Cond? instruction&  
                instruction,wxyz  
        end macro  
end iterate 


TestSimpler = 0

if TestSimpler = 1
;Times :   Full 8 COG ->  2 passes, 2.2 seconds, 16487 bytes.
rept 511*8  
         pcADD 07H,03H  ; Comment
end rept        
else
; Times: 
;  Full 32 IF_  -> 2 passes, 2.2 seconds, 16455 bytes.
;  Added '#'   -> 2 passes, 2.2 seconds, 16455 bytes.
LoopC = (512/15)        ; 15 lines - fill all 8 COGs to allow speed tests
rept LoopC*8 
IF_E     pcADD 0AH,05H   ;Comment
IF_NE    pcADD 0AH,#05H  ;Comment
IF_A     pcADD 0AH,05H   ;Comment
IF_B     pcADD 0AH,05H   ;Comment
         pcADD 07H,03H   ;Comment
IF_E     pcSUB 0AH,05H   ;Comment
IF_NE    pcSUB 0AH,#05H  ;Comment
IF_A     pcSUB 0AH,05H   ;Comment
IF_B     pcSUB 0AH,05H   ;Comment
         pcSUB 07H,03H   ;Comment
IF_E     pcADD 0AH,#05H  
IF_NE    pcADD 0AH,05H   
IF_A     pcADD 0AH,#05H  
IF_B     pcADD 0AH,#05H  
         pcADD 07H,#03H  
end rept        
end if 
    
Post 21 Sep 2016, 21:01
View user's profile Send private message Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 21 Sep 2016, 23:36
Prefix is working nicely...

Now I'd appreciate some tips on the best way to manage Opcode suffix options.., which map to the ZCR opcode bits.

Good news is only WZ WC NR are legal, (any case) bad news is they can be in any combination or order.

Code:
;           ZCRi  
;XOR 011011 001i cccc ddddddddd sssssssss
         tXOR 0AH,#04H  ; Suffix Comment
IF_Z     tXOR 0AH,#05H           ;ZCR          = 001, default
IF_NZ    tXOR 0AH,#05H  WC       ;C field set    011
IF_A     tXOR 0AH,#05H  WZ       ;Z field set    101 
IF_B     tXOR 0AH,#05H  NR       ;R field clr    000
IF_C     tXOR 0AH,#05H  WZ,WC    ;Z,C both set   111 
IF_C     tXOR 0AH,#05H  WC,wz    ;Z,C both set   111  Same result
IF_C     tXOR 0AH,#05H  WZ,NR    ;Z set, R clr   100 
IF_C     tXOR 0AH,#05H  NR,WZ    ;Z set, R clr   100 Same result etc
IF_C     tXOR 0AH,#05H  wc,NR    ;C set, R clr   010 
IF_NC    tXOR 0AH,#05H  WZ,WC,nr ;Z,C set, R clr 110 etc  
    


I have a subset working, somewhat....
Code:
          tXOR 0AH,#05H  ; Suffix Comment
;if TestSuffix=1
          tXOR 0AH,#05H,WC       ;C field set    011
          tXOR 0AH,#05H,WZ       ;Z field set    101 
          tXOR 0AH,#05H,NR       ;R field clr    000
          tXOR 0AH,#05H, wc      ;C field set    011
          tXOR 0AH,#05H, wz      ;Z field set    101 
          tXOR 0AH,#05H, nr      ;R field clr    000
    

Caveats are this form needs an added semicolon, which is best avoided.
- plus the IF_ handling above tangles with following params, so I removed that for testing.

Ideal goal is this syntax

Code:
IF_NC    tXOR 0AH,#05H  WZ,WC,nr ;Z,C set, R clr 110 etc      
Post 21 Sep 2016, 23:36
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 22 Sep 2016, 06:41
You could do it with a long sequence of matches for every possible combination, but that would be slow and considering the time it took to assemble your previous sample on your machine it is perhaps better to avoid such solution. Therefore I'd suggest defining the suffixes as symbolic values containing some special combination of symbols that can be easily matched and cut off from the base instruction:
Code:
NR equ :+:001b
WC equ :+:010b
WZ equ :+:100b    
The processing may then look like:
Code:
        macro IF_#Cond? tail&
                match instruction :+:suffix, tail
                        local buffer,flags
                        buffer equ suffix
                        flags = 0
                        while 1
                                match first =, :+:next, buffer
                                        flags = flags or first
                                        buffer equ next
                                else
                                        flags = flags or buffer
                                        break
                                end match
                        end while
                        flags = flags xor 1 ; NR is reversed
                        base.instruction,wxyz,flags
                else
                        base.tail,wxyz
                end match
        end macro    
I modified only the IF_Cond variant, you'd also need to do similar thing with all the non-prefixed instructions.
Post 22 Sep 2016, 06:41
View user's profile Send private message Visit poster's website Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 22 Sep 2016, 07:12
Tomasz Grysztar wrote:
Therefore I'd suggest defining the suffixes as symbolic values containing some special combination of symbols that can be easily matched and cut off from the base instruction:
Code:
NR equ :+:001b    

It coughs on the :+: and the manual has no examples ?
Or, was that a placekeeper for some special String prefix combination ?

Tomasz Grysztar wrote:

base.instruction,wxyz,flags


When I tried a general form with wxyz and flags both as params, the macro passing seemed to get confused as one or the other may be present alone ?
Rather than params, I may try a globals approach ?
Post 22 Sep 2016, 07:12
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 22 Sep 2016, 07:35
jmg wrote:
Tomasz Grysztar wrote:
Therefore I'd suggest defining the suffixes as symbolic values containing some special combination of symbols that can be easily matched and cut off from the base instruction:
Code:
NR equ :+:001b    

It coughs on the :+: and the manual has no examples ?
Or, was that a placekeeper for some special String prefix combination ?
You can choose the sequence of symbols freely, they are only used here so that the MATCH inside the macro is able to detect boundary between regular arguments and suffix (in general we cannot use whitespace as a delimited because the previous argument may itself be a complex expression and contain some whitespace, like "1 shl 4"). However when you use equates like this, you always need to use MATCH to cut off the special sequence.

jmg wrote:
When I tried a general form with wxyz and flags both as params, the macro passing seemed to get confused as one or the other may be present alone ?
Rather than params, I may try a globals approach ?
You can try globals if you prefer, but it also not unusual to use parameter with empty values like this:
Code:
macro example ParD*,ParS*,ParC:1111b,ParF:001b
        db ParD,ParS,ParC,ParF
end macro

example 0Ah,05h         ; two defaults
example 0Ah,05h,1001b   ; default ParF
example 0Ah,05h,,111b   ; default ParC
example 0Ah,05h,0,111b  ; no defaults    
Post 22 Sep 2016, 07:35
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 22 Sep 2016, 07:44
jmg wrote:
It coughs on the :+: and the manual has no examples ?
Or, was that a placekeeper for some special String prefix combination ?

Actually, your comment gave me an inspiration for a better idea:
Code:
define NR SUFF -001b
define WC SUFF 010b
define WZ SUFF 100b
define SUFF    
When we define "SUFF" with an empty value like this, it is going to be ignored when calculating expressions, but MATCH will still be able to detect it, because MATCH only does single pass replacing the symbolic variables with their values:
Code:
        macro IF_#Cond? tail&
                match instruction =SUFF suffix, tail
                        local flags
                        flags = 001b
                        iterate flag,suffix
                                if flag >= 0
                                        flags = flags or flag
                                else
                                        flags = flags and not -flag
                                end if
                        end iterate
                        base.instruction,wxyz,flags
                else 
                        base.tail,wxyz 
                end match 
        end macro    
This should be processed faster.
Post 22 Sep 2016, 07:44
View user's profile Send private message Visit poster's website Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 22 Sep 2016, 07:55
Tomasz Grysztar wrote:
You can choose the sequence of symbols freely, they are only used here so that the MATCH inside the macro is able to detect boundary between regular arguments and suffix


Hmm, when I use the exact
Code:
NR equ :+:001b    

It spits 'invalid expression' on that line ?

Tomasz Grysztar wrote:

You can try globals if you prefer, but it also not unusual to use parameter with empty values ...


Ah, ok, I can see that works with ,, to tell the ASM where to place them, but ideally I want to parse white space(s) after the IF_Cond, and another white space(s) before the optional WC,WZ,WR , so that may be better to define a default, and at the end of each opcode, set back to default.
Then, empty fields update as they appear, and either or both missing, has no effect on macro param order.

I think the flag-scan outline has promise, if I can get past the error messages...

I'm unclear on 'tail', 'suffix', 'base' and 'instruction' word interactions in the example, they do not seem to be keywords ?
Post 22 Sep 2016, 07:55
View user's profile Send private message Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 22 Sep 2016, 08:07
Tomasz Grysztar wrote:
Actually, your comment gave me an inspiration for a better idea:
Code:
define NR SUFF -001b
    


That also solves the error message....

Tomasz Grysztar wrote:

Code:
        macro IF_#Cond? tail&
                match instruction =SUFF suffix, tail
                        local flags
                        flags = 001b
                        iterate flag,suffix
                                if flag >= 0
                                        flags = flags or flag
                                else
                                        flags = flags and not -flag
                                end if
                        end iterate
                        base.instruction,wxyz,flags
                else 
                        base.tail,wxyz 
                end match 
        end macro    

That seems to cough on base.instruction, but I think with globals, I can use a single instruction call and get the white space tolerance ?
Post 22 Sep 2016, 08:07
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 22 Sep 2016, 08:17
jmg wrote:
Hmm, when I use the exact
Code:
NR equ :+:001b    

It spits 'invalid expression' on that line ?
You probably have some macro that intercepts this line and tries to do something with the value. This is a perfectly valid fasm/fasmg construction on its own. (Perhaps you used my symbol displaying macro from the other thread? It won't work with constructions like this because the value is not a number).

jmg wrote:
That seems to cough on base.instruction
This assumes that there is a separate namespace called "base" where you'd have low-level instruction handlers:
Code:
define base
namespace base
        macro pcADD? ParD*,ParS*,ParC:1111b,ParF:001b
        ; ...  
end namespace    


jmg wrote:
I'm unclear on 'tail', 'suffix', 'base' and 'instruction' word interactions in the example, they do not seem to be keywords ?
They are parameters, you can choose any names for them.
Post 22 Sep 2016, 08:17
View user's profile Send private message Visit poster's website Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 22 Sep 2016, 10:16
Good progress, all the complex cases now work, but the no IF_ case needs work.

now gParC is global, I think it would be cleaner to push the iterate flag,suffix
block into the G_CDS macro, ( to avoid duplication) which I think means ParS*& ?


Code:
define NR SUFF -001b 
define WC SUFF 010b 
define WZ SUFF 100b 
define SUFF

gParC = 1111b ; default
gZCR  = 001b 

macro G_CDS? ParD*,ParS*   
   gCDS  = (gZCR shl 23) + (gParC and 0xf) shl 18 + (ParD and 0x1ff) shl 9 + ParS and 0x1ff
   gZCR  = 001b  ; restore default, after use
   gParC = 1111b ; restore default, after use
end macro

;           ZCRi  
;XOR 011011 001i cccc ddddddddd sssssssss
;    109876 5432 1098 765432109 876543210
macro qXOR? ParD*,ParS* ; ParC, ZCR now global
    G_CDS ParD,ParS    ; Globals avois WC into ParC 
        match #data, ParS
          dd (011011_000_1b shl 22) + gCDS
        else  
          dd (011011_000_0b shl 22) + gCDS
        end match  
end macro 

    
iterate <Cond,wxyz>,\
ALWAYS,1111b,NEVER,0000b,E,1010b,NE,0101b,A,0001b,B,1100b,AE,0011b,BE,1110b,C,1100b,NC,0011b,\
Z,1010b,NZ,0101b,C_EQ_Z,1001b,C_NE_Z,0110b,C_AND_Z,1000b,C_AND_NZ,0100b,NC_AND_Z,0010b,NC_AND_NZ,0001b,\ 
C_OR_Z,1110b,C_OR_NZ,1101b,NC_OR_Z,1011b,NC_OR_NZ,0111b,Z_EQ_C,1001b,Z_NE_C,0110b,Z_AND_C,1000b,\  
Z_AND_NC,0010b,NZ_AND_C,0100b,NZ_AND_NC,0001b,Z_OR_C,1110b,Z_OR_NC,1011b,NZ_OR_C,1101b,NZ_OR_NC,0111b  
    macro qIF_#Cond? tail& 
        gParC = wxyz ; new CC value
        match instruction =SUFF suffix, tail 
            local flags 
            flags = 001b 
            iterate flag,suffix   ; comma delimited list
                if flag >= 0 
                    flags = flags or flag 
                else  ;NR
                    flags = flags and not -flag 
                end if 
            end iterate 
                        gZCR = flags
            instruction   ; trimmed of tail
        else  
                    gZCR = 001b
            tail       ; no-trim, tail is the opcode
        end match  
    end macro
end iterate 
qIF_Z     qXOR 0AH,#05H  WC       ;C field set    011
qIF_Z     qXOR 0AH,#05H  WZ       ;Z field set    101 
qIF_Z     qXOR 0AH,#05H  WZ,WC    ;ZC field set   111 
qIF_Z     qXOR 0AH,#05H  WC,WZ    ;ZC field set   111 
qIF_Z     qXOR 0AH,#05H  NR       ;R field clr    000
          qXOR 0AH,#05H           
          qXOR 0AH,#05H  WC  ; << this case fails, can we push iterate flag,suffix into G_CDS?        
qIF_ALWAYS qXOR 0AH,#05H 
qIF_ALWAYS qXOR 0AH,#05H WZ
qIF_ALWAYS qXOR 0AH,#05H WZ,WC
qIF_ALWAYS qXOR 0AH,#05H WZ,WC,NR
; field checks 
        dd      (001b shl 23)  ; default
        dd      (101b shl 23)  ; wz
        dd      (111b shl 23)  ; wz wc
        dd      (000b shl 23)  ; nr
    
Post 22 Sep 2016, 10:16
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 22 Sep 2016, 12:30
jmg wrote:
now gParC is global, I think it would be cleaner to push the iterate flag,suffix
block into the G_CDS macro, ( to avoid duplication) which I think means ParS*& ?
Yes, you need "&" there and you need to move the entire MATCH block:
Code:
macro G_CDS? D*,S_Suffix*&
   ParD = D
   gZCR = 001b
   match S =SUFF suffix, S_Suffix
       ParS = S
       local flags
       iterate flag,suffix   ; comma delimited list
           if flag >= 0
               gZCR = gZCR or flag
           else  ;NR
               gZCR = gZCR and not -flag
           end if
       end iterate
   else
       ParS = S_Suffix
   end match
   gCDS  = (gZCR shl 23) + (gParC and 0xf) shl 18 + (ParD and 0x1ff) shl 9 + ParS and 0x1ff
   gZCR  = 001b  ; restore default, after use 
   gParC = 1111b ; restore default, after use 
end macro 

;           ZCRi   
;XOR 011011 001i cccc ddddddddd sssssssss 
;    109876 5432 1098 765432109 876543210 
macro qXOR? ParD*,ParS*& ; ParC, ZCR now global
    G_CDS ParD,ParS    ; Globals avois WC into ParC  
        match #data, ParS 
          dd (011011_000_1b shl 22) + gCDS 
        else   
          dd (011011_000_0b shl 22) + gCDS 
        end match   
end macro     
Post 22 Sep 2016, 12:30
View user's profile Send private message Visit poster's website Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 22 Sep 2016, 20:57
Thanks, that's great! - I've now moved it, & passes all tests...

Code:
; ~~~~~~~~~~~~~~ Now Expanded to support Suffix too.. ~~~~~~~~~~~~~~~~~

;web suggestion 
define NR SUFF -001b 
define WC SUFF 010b 
define WZ SUFF 100b 
define SUFF

gParC = 1111b ; default, globalV init

macro G_CDS? ParD*,S_Suffix*&  ; & for ParS and any suffix controls
   gZCR = 001b ; default
   match S =SUFF suffix, S_Suffix  ;splits S,
       ParS = S 
       local flags 
       iterate flag,suffix   ; comma delimited list 
           if flag >= 0 
               gZCR = gZCR or flag 
           else  ;NR 
               gZCR = gZCR and not -flag 
           end if 
       end iterate 
   else 
       ParS = S_Suffix 
   end match 
   gCDS  = (gZCR shl 23) + gParC shl 18 + (ParD and 0x1ff) shl 9 + ParS and 0x1ff 
   gParC = 1111b ; restore global default, after use  
end macro  

;           ZCRi    
;XOR 011011 001i cccc ddddddddd sssssssss  
;    109876 5432 1098 765432109 876543210  
macro qXOR? ParD*,ParS*& ; ParC now global, ZCR via any suffix 
    G_CDS ParD,ParS     
    match #data, ParS  
        dd (011011_000_1b shl 22) + gCDS  
    else    
        dd (011011_000_0b shl 22) + gCDS  
    end match    
end macro 

; ~~~~~~~~~ Build 32 IF_ variants ~~~~~~~~~~~~    
iterate <Cond,wxyz>,\
ALWAYS,1111b,NEVER,0000b,E,1010b,NE,0101b,A,0001b,B,1100b,AE,0011b,BE,1110b,C,1100b,NC,0011b,\
Z,1010b,NZ,0101b,C_EQ_Z,1001b,C_NE_Z,0110b,C_AND_Z,1000b,C_AND_NZ,0100b,NC_AND_Z,0010b,NC_AND_NZ,0001b,\ 
C_OR_Z,1110b,C_OR_NZ,1101b,NC_OR_Z,1011b,NC_OR_NZ,0111b,Z_EQ_C,1001b,Z_NE_C,0110b,Z_AND_C,1000b,\  
Z_AND_NC,0010b,NZ_AND_C,0100b,NZ_AND_NC,0001b,Z_OR_C,1110b,Z_OR_NC,1011b,NZ_OR_C,1101b,NZ_OR_NC,0111b  
    macro qIF_#Cond? instruction&  
        gParC = wxyz ; apply CC value, now global
        instruction 
    end macro  
end iterate 

; ~~~~~~~~~ Test coverage ~~~~~~~~~~~~
qIF_Z      qXOR 0AH,#05H  WC       ;C field set    011
qIF_Z      qXOR 0AH,#05H  WZ       ;Z field set    101 
qIF_Z      qXOR 0AH,#05H  WZ,WC    ;ZC field set   111 
qIF_Z      qXOR 0AH,#05H  WC,WZ    ;ZC field set   111 
qIF_Z      qXOR 0AH,#05H  NR       ;R field clr    000
           qXOR 0AH,#05H           
           qXOR 0AH,#05H  WC   ; Fixed with  push iterate flag,suffix into G_CDS?        
qIF_ALWAYS qXOR 0AH,#05H 
qIF_ALWAYS qXOR 0AH,#05H WZ
qIF_ALWAYS qXOR 0AH,#05H WZ,WC
qIF_ALWAYS qXOR 0AH,#05H WZ,WC,NR
    
Post 22 Sep 2016, 20:57
View user's profile Send private message Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 14 Oct 2016, 01:29
Cleaning this up a little for more tests, and I find an unexpected speed gain..

;0.99
; Listing ON -> 2 passes, 2.4 seconds, 16547 bytes. 266k LST
; Listing OFF -> 2 passes, 0.4 seconds, 16547 bytes. 80 byte LST

; Clean-up, removed obsolete test code, placed macros first, - ? much faster, maybe due to 1 pass now ?
; 1 pass, 1.4 seconds, 16464 bytes. 251k LST file
;
; more edits
; 1 pass, 1.2 seconds, 16464 bytes. 12k source 251k LST file

; 1 pass, 1.2 seconds, 16464 bytes. 30k source (+18k comments to check file read speed )
; 1 pass, 0.2 seconds, 16464 bytes. LST off, still ~ 6x slower with LST on.

File size created shrank just slightly in the clean-up, but the speed doubled.

Not quite what I expected ?

I guess this means each pass adds the same time to the assembly ? - but the LST seems to dominate, and that is exactly the same in 1 or 2 passes ?
Post 14 Oct 2016, 01:29
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 14 Oct 2016, 06:06
In fasmg additional passes are only very slightly faster than the first one, so the total time is roughly the multiple of a single pass. In fasm 1 it was different, since it had a separate preprocessor stage after which the passes were performed by pre-compiled bytecode, so additional passes did not add that much time. But to provide the kind of features that fasmg has the other approach was needed.
Post 14 Oct 2016, 06:06
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.