Skip to content

Commit b960147

Browse files
Added support for inplace XOR.
1 parent f151bbe commit b960147

File tree

3 files changed

+125
-1
lines changed

3 files changed

+125
-1
lines changed

ugbc/src/targets/common/_infrastructure.c

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3523,6 +3523,113 @@ void variable_add_inplace_mt( Environment * _environment, char * _source, char *
35233523

35243524
}
35253525

3526+
void variable_xor_inplace( Environment * _environment, char * _source, int _destination ) {
3527+
3528+
if ( _destination ) {
3529+
3530+
Variable * source = variable_retrieve( _environment, _source );
3531+
3532+
switch( VT_BITWIDTH( source->type ) ) {
3533+
case 32:
3534+
cpu_xor_32bit_const( _environment, source->realName, _destination, source->realName );
3535+
break;
3536+
case 16:
3537+
cpu_xor_16bit_const( _environment, source->realName, _destination, source->realName );
3538+
break;
3539+
case 8:
3540+
cpu_xor_8bit_const( _environment, source->realName, _destination, source->realName );
3541+
break;
3542+
case 1:
3543+
case 0:
3544+
CRITICAL_XOR_INPLACE_UNSUPPORTED( _source, DATATYPE_AS_STRING[source->type]);
3545+
}
3546+
3547+
}
3548+
}
3549+
3550+
/**
3551+
* @brief Add two variable and return the sum of them on the first
3552+
*
3553+
* This function allows you to sum the value of two variables. Note
3554+
* that both variables must pre-exist before the operation,
3555+
* under penalty of an exception.
3556+
*
3557+
* @pre _source and _destination variables must exist
3558+
*
3559+
* @param _environment Current calling environment
3560+
* @param _source Source variable's name and destination of sum
3561+
* @param _destination Value to sum
3562+
* @throw EXIT_FAILURE "Destination variable does not cast"
3563+
* @throw EXIT_FAILURE "Source variable does not exist"
3564+
*/
3565+
void variable_xor_inplace_vars( Environment * _environment, char * _source, char * _destination ) {
3566+
3567+
Variable * source = variable_retrieve( _environment, _source );
3568+
Variable * target = variable_retrieve( _environment, _destination );
3569+
3570+
if ( source->type != target->type ) {
3571+
target = variable_cast( _environment, _destination, source->type );
3572+
if ( ! target ) {
3573+
CRITICAL_VARIABLE(_destination);
3574+
}
3575+
}
3576+
3577+
switch( VT_BITWIDTH( source->type ) ) {
3578+
case 32:
3579+
cpu_xor_32bit( _environment, source->realName, target->realName, source->realName );
3580+
break;
3581+
case 16:
3582+
cpu_xor_16bit( _environment, source->realName, target->realName, source->realName );
3583+
break;
3584+
case 8:
3585+
cpu_xor_8bit( _environment, source->realName, target->realName, source->realName );
3586+
break;
3587+
case 1:
3588+
case 0:
3589+
CRITICAL_XOR_INPLACE_UNSUPPORTED( _source, DATATYPE_AS_STRING[source->type]);
3590+
}
3591+
3592+
}
3593+
3594+
/**
3595+
* @brief Add two variable and return the sum of them on the first
3596+
*
3597+
* This function allows you to sum the value of two variables. Note
3598+
* that both variables must pre-exist before the operation,
3599+
* under penalty of an exception.
3600+
*
3601+
* @pre _source and _destination variables must exist
3602+
*
3603+
* @param _environment Current calling environment
3604+
* @param _source Source variable's name and destination of sum
3605+
* @param _destination Value to sum
3606+
* @throw EXIT_FAILURE "Destination variable does not cast"
3607+
* @throw EXIT_FAILURE "Source variable does not exist"
3608+
*/
3609+
void variable_xor_inplace_mt( Environment * _environment, char * _source, char * _destination ) {
3610+
3611+
parser_array_init( _environment );
3612+
parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
3613+
Variable * array = variable_retrieve( _environment, _source );
3614+
if ( array->type != VT_TARRAY ) {
3615+
CRITICAL_NOT_ARRAY( _source );
3616+
}
3617+
Variable * value = variable_move_from_array( _environment, array->name );
3618+
parser_array_cleanup( _environment );
3619+
3620+
variable_xor_inplace_vars( _environment, value->name, _destination );
3621+
3622+
parser_array_init( _environment );
3623+
parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
3624+
array = variable_retrieve( _environment, _source );
3625+
if ( array->type != VT_TARRAY ) {
3626+
CRITICAL_NOT_ARRAY( _source );
3627+
}
3628+
variable_move_array( _environment, array->name, value->name );
3629+
parser_array_cleanup( _environment );
3630+
3631+
}
3632+
35263633
/**
35273634
* @brief Make a differenze between two variable and return the difference of them
35283635
*
@@ -8075,7 +8182,7 @@ Variable * variable_move_from_array_byte( Environment * _environment, Variable *
80758182
}
80768183

80778184
cpu_move_8bit( _environment, precalculatedOffset->realName, result->realName );
8078-
8185+
80798186
return result;
80808187
}
80818188
}

ugbc/src/ugbc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3225,6 +3225,7 @@ typedef struct _Environment {
32253225
#define CRITICAL_CANNOT_OPEN_FILE(f,n) CRITICAL3("E305 - cannot open file", f, n );
32263226
#define CRITICAL_CANNOT_READ_FILE(f,n) CRITICAL3("E306 - cannot read file", f, n );
32273227
#define CRITICAL_CANNOT_WRITE_FILE(f,n) CRITICAL3("E307 - cannot write file", f, n );
3228+
#define CRITICAL_XOR_INPLACE_UNSUPPORTED(v,t) CRITICAL3("E308 - cannot use inplace XOR with this datatype", v, t );
32283229

32293230
#define WARNING( s ) if ( ((struct _Environment *)_environment)->warningsEnabled) { fprintf(stderr, "WARNING during compilation of %s:\n\t%s at %d\n", ((struct _Environment *)_environment)->sourceFileName, s, ((struct _Environment *)_environment)->yylineno ); }
32303231
#define WARNING2( s, v ) if ( ((struct _Environment *)_environment)->warningsEnabled) { fprintf(stderr, "WARNING during compilation of %s:\n\t%s (%s) at %d\n", ((struct _Environment *)_environment)->sourceFileName, s, v, _environment->yylineno ); }
@@ -5020,6 +5021,9 @@ Variable * variable_temporary( Environment * _environment, Variable
50205021
VariableType variable_type_from_numeric_value( Environment * _environment, int _number );
50215022
Variable * variable_resident( Environment * _environment, VariableType _type, char * _meaning );
50225023
Variable * variable_xor( Environment * _environment, char * _left, char * _right );
5024+
void variable_xor_inplace( Environment * _environment, char * _source, int _dest );
5025+
void variable_xor_inplace_vars( Environment * _environment, char * _source, char * _dest );
5026+
void variable_xor_inplace_mt( Environment * _environment, char * _source, char * _destination );
50235027
Variable * varptr( Environment * _environment, char * _identifier );
50245028
void volume( Environment * _environment, int _volume, int _channels );
50255029
void volume_vars( Environment * _environment, char * _volume, char * _channels );

ugbc/src/ugbc.y

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6269,6 +6269,18 @@ add_definition :
62696269
}
62706270
;
62716271

6272+
xor_definition :
6273+
Identifier OP_COMMA expr {
6274+
variable_xor_inplace_vars( _environment, $1, $3 );
6275+
}
6276+
| Identifier OP_COMMA OP_HASH const_expr {
6277+
variable_xor_inplace( _environment, $1, $4 );
6278+
}
6279+
| OSP Identifier CSP OP_COMMA expr {
6280+
variable_xor_inplace_mt( _environment, $2, $5 );
6281+
}
6282+
;
6283+
62726284
swap_definition :
62736285
Identifier as_datatype_suffix_optional OP_COMMA Identifier as_datatype_suffix_optional {
62746286
if ( $2 != $5 ) {
@@ -9689,6 +9701,7 @@ statement2nc:
96899701
| ADD add_definition
96909702
| MUL mul_definition
96919703
| DIV div_definition
9704+
| XOR xor_definition
96929705
| POKE poke_definition
96939706
| POKEW pokew_definition
96949707
| POKED poked_definition

0 commit comments

Comments
 (0)