I need help to get this right. The change to the compiler is actually very small. But, getting the syntax right is very critical.
The other day I was contact regarding porting LATA ^=(1 << 6); to GCBASIC. This is a question I have seen many times.
This operation equates to LATA = LATA XOR 64 but we have lots of options in GCBASIC ( and, I am sure there are more ways to do this) but none are an like for like implementation.
All of the following work - the first two are optimised but all but the last option change the context of the shift operation.
Instruction
ASM Size
Comment
PORTA = PORTA xor 64
2
The user have to calculate the bit value ( 64 )
PORTA = PORTA XOR 0b01000000
2
The user have to calculate the bit value ( 64 )
PORTA.6 = NOT PORTA.6
6
Logically correct and easy to use
PORTA.6 = PORTA.6 XOR 1
8
This option is useful but code is large.
SetWith( PORTA.6, !PORTA.6 )
9
The oldest GCBASI C way!!!
PORTA = PORTA XOR FnLSR ( 1, 6 )
19
A true maths conversion... the slowest to execute.
The GCBASIC compiler really should convert (1 << 6) as follows
#chip 16F877a#option Explicit#DEFINE myShift 4 // could be any value constant/register mask. I am using the constant value of 4Doporta=portaXOR(1<<myShift)wait100msLoop
Explanation:
porta is typically a register that controls the state of the pins on port A of the microcontroller.
XOR (exclusive OR) is a bitwise operation that toggles specific bits.
1 << myShift: This is a bitwise left shift operation. It shifts the bit 1 to the left by myShift positions. So 1 << 4 equals 16 in decimal, or 0b10000 in binary.
The XOR operation will toggle the bit at position 4 of register.
ASM
The ASM generated follows. It is optimised and is easy to understand.
Instruction
ASM Size
Comment
porta = porta XOR ( 1 << myShift )
2
Simple and fast.
This is generated by my prototype implementation.
;porta = porta XOR ( 1 << myShift )
movlw 16
banksel PORTA
xorwf PORTA,F
[EDITED] The shift operations would have to support constants only. There is huge difference between using constants to variables. Constants can be calculated during compilation. Variables are a run time coding and is not scope for this potential piece of work.
This seems to be so easy but this where I need your thoughts to get the syntax right.
How to handle errors? what are errors? etc.
Is this valid syntax ? porta = porta XOR 1 << myShiftNo parentheses
How handle ? porta = porta XOR 1 << Where there is no shift parameter
How handle ? porta = porta XOR 1 << undefined_consant Where there is no shift parameter as the constant does not exist.
How to handle ? Using a variable as a shift parameter? Just throw a compilation error.
Other things that need to be handled ?
Evan
Last edit: Anobium 2025-01-08
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Change of plan ... as I posted a private message to Chris Roper ( he wrote many of the Bitwise operations many years ago... I had a flash of inspiration.
Support of variables as the parameters is easily do able. If either of the parameters are not constants then call then transform the instruction ( in the compier) to call methods FnLSL() or FnLSR() within the compiled ASM - the user source remains the same!
Help and comments please.
I need help to get this right. The change to the compiler is actually very small. But, getting the syntax right is very critical.
The other day I was contact regarding porting
LATA ^=(1 << 6);
to GCBASIC. This is a question I have seen many times.This operation equates to
LATA = LATA XOR 64
but we have lots of options in GCBASIC ( and, I am sure there are more ways to do this) but none are an like for like implementation.All of the following work - the first two are optimised but all but the last option change the context of the shift operation.
PORTA = PORTA xor 64
PORTA = PORTA XOR 0b01000000
PORTA.6 = NOT PORTA.6
PORTA.6 = PORTA.6 XOR 1
SetWith( PORTA.6, !PORTA.6 )
PORTA = PORTA XOR FnLSR ( 1, 6 )
The GCBASIC compiler really should convert (1 << 6) as follows
Explanation:
porta is typically a register that controls the state of the pins on port A of the microcontroller.
XOR (exclusive OR) is a bitwise operation that toggles specific bits.
1 << myShift: This is a bitwise left shift operation. It shifts the bit 1 to the left by myShift positions. So 1 << 4 equals 16 in decimal, or 0b10000 in binary.
The XOR operation will toggle the bit at position 4 of register.
ASM
The ASM generated follows. It is optimised and is easy to understand.
porta = porta XOR ( 1 << myShift )
This is generated by my prototype implementation.
Syntax and Error Handling
result_register = ( VALUE_CONSTANT [<< | >> ] NUM_OF_POSITIONS_CONSTANT )
[EDITED] The shift operations would have to support constants only. There is huge difference between using constants to variables. Constants can be calculated during compilation. Variables are a run time coding and is not scope for this potential piece of work.
See next post regarding variables as parameters
This seems to be so easy but this where I need your thoughts to get the syntax right.
How to handle errors? what are errors? etc.
Is this valid syntax ?
porta = porta XOR 1 << myShift
No parenthesesHow handle ?
porta = porta XOR 1 <<
Where there is no shift parameterHow handle ?
porta = porta XOR 1 << undefined_consant
Where there is no shift parameter as the constant does not exist.How to handle ? Using a variable as a shift parameter? Just throw a compilation error.
Other things that need to be handled ?
Evan
Last edit: Anobium 2025-01-08
Change of plan ... as I posted a private message to Chris Roper ( he wrote many of the Bitwise operations many years ago... I had a flash of inspiration.
Support of variables as the parameters is easily do able. If either of the parameters are not constants then call then transform the instruction ( in the compier) to call methods FnLSL() or FnLSR() within the compiled ASM - the user source remains the same!
**Prototype Compiler Implementation **
Generated ASM!
Crikey - this works!!
I have completed an implementation.
Handles use of constants or variables.
or
There is lots of syntax checking but it may not cover all cases.
Anyone interested in testing?