ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
pow.c
Go to the documentation of this file.
1/*****************************************************************************
2 * ugBASIC - an isomorphic BASIC language compiler for retrocomputers *
3 *****************************************************************************
4 * Copyright 2021-2026 Marco Spedaletti (asimov@mclink.it)
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *----------------------------------------------------------------------------
18 * Concesso in licenza secondo i termini della Licenza Apache, versione 2.0
19 * (la "Licenza"); è proibito usare questo file se non in conformità alla
20 * Licenza. Una copia della Licenza è disponibile all'indirizzo:
21 *
22 * http://www.apache.org/licenses/LICENSE-2.0
23 *
24 * Se non richiesto dalla legislazione vigente o concordato per iscritto,
25 * il software distribuito nei termini della Licenza è distribuito
26 * "COSÌ COM'È", SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o
27 * implicite. Consultare la Licenza per il testo specifico che regola le
28 * autorizzazioni e le limitazioni previste dalla medesima.
29 ****************************************************************************/
30
31/****************************************************************************
32 * INCLUDE SECTION
33 ****************************************************************************/
34
35#include "../../ugbc.h"
36
37/****************************************************************************
38 * CODE SECTION
39 ****************************************************************************/
40
41extern char DATATYPE_AS_STRING[][16];
42
56/* <usermanual>
57@keyword POW
58
59@english
60The ''POW'' instruction is short for "power" and is used to calculate the
61power of a number. In other words, it allows you to raise a base number
62to a certain exponent. It multiplies the base by itself a number of times
63equal to the exponent. For example, ''POW(2, 3)'' means to multiply 2
64by itself 3 times: ''2 * 2 * 2''. The variables used for the base and
65exponent must be integer. So can be computationally expensive for very large
66exponents. In some cases, there may be more efficient algorithms
67for calculating powers.
68
69@italian
70L'istruzione ''POW'' è l'abbreviazione di "power" (potenza) e viene
71utilizzata per calcolare la potenza di un numero. In altre parole,
72consente di elevare un numero di base a un certo esponente. Moltiplica
73la base per se stessa un numero di volte pari all'esponente. Ad esempio,
74''POW(2, 3)'' significa moltiplicare 2 per se stesso 3 volte: ''2 * 2 * 2''.
75Le variabili utilizzate per la base e l'esponente devono essere intere.
76Quindi può essere computazionalmente costoso per esponenti molto grandi.
77In alcuni casi, potrebbero esserci algoritmi più efficienti per
78calcolare le potenze.
79
80@syntax = POW( base, exponent )
81@syntax = base ^ exponent
82
83@example pitagora = POW(a,2) + b^2 + POW(c,2)
84
85@usedInExample maths_example_01.bas
86
87@target all
88@verified
89</usermanual> */
90
91Variable * powering( Environment * _environment, char * _base, char * _exponential ) {
92
93 Variable * base = variable_retrieve( _environment, _base );
94 Variable * exponential = variable_retrieve_or_define( _environment, _exponential, VT_SWORD, 0 );
95
96 Variable * result, * temporary;
97
98 switch( base->type ) {
99 case VT_SBYTE:
100 case VT_BYTE:
101 case VT_SWORD:
102 case VT_WORD:
103 case VT_POSITION:
104 case VT_FLOAT:
105 break;
106 default:
108 }
109
110 switch( exponential->type ) {
111 case VT_SBYTE:
112 case VT_BYTE:
113 case VT_SWORD:
114 case VT_WORD:
115 case VT_POSITION:
116 break;
117 default:
118 CRITICAL_POW_UNSUPPORTED( _exponential, DATATYPE_AS_STRING[exponential->type]);
119 }
120
122
123 char endLabel[MAX_TEMPORARY_STORAGE]; sprintf(endLabel, "%send", label);
124
125 Variable * counter = variable_cast( _environment, exponential->name, VT_BYTE );
126 switch( VT_BITWIDTH( base->type ) ) {
127 case 16:
128 result = variable_temporary( _environment, VT_SIGNED( base->type ) ? VT_SDWORD : VT_DWORD, "(result of pow)");
129 temporary = variable_temporary( _environment, VT_SIGNED( base->type ) ? VT_SDWORD : VT_DWORD, "(result of pow)");
130 variable_store( _environment, result->name, 1 );
131 cpu_bveq( _environment, counter->realName, endLabel );
132 cpu_label( _environment, label );
133 #ifdef CPU_BIG_ENDIAN
134 {
135 char resultRealName[MAX_TEMPORARY_STORAGE]; sprintf( resultRealName, "%s", address_displacement(_environment, result->realName, "2") );
136 cpu_math_mul_16bit_to_32bit( _environment, base->realName, resultRealName, temporary->realName, VT_SIGNED( base->type ) );
137 }
138 #else
139 cpu_math_mul_16bit_to_32bit( _environment, base->realName, result->realName, temporary->realName, VT_SIGNED( base->type ) );
140 #endif
141 cpu_move_32bit( _environment, temporary->realName, result->realName );
142 cpu_dec( _environment, counter->realName );
143 cpu_bvneq( _environment, counter->realName, label );
144 cpu_label( _environment, endLabel );
145 break;
146 case 8:
147 result = variable_temporary( _environment, VT_SIGNED( base->type ) ? VT_SWORD : VT_WORD, "(result of pow)");
148 temporary = variable_temporary( _environment, VT_SIGNED( base->type ) ? VT_SDWORD : VT_DWORD, "(result of pow)");
149 variable_store( _environment, result->name, 1 );
150 cpu_bveq( _environment, counter->realName, endLabel );
151 cpu_label( _environment, label );
152 #ifdef CPU_BIG_ENDIAN
153 {
154 char resultRealName[MAX_TEMPORARY_STORAGE]; sprintf( resultRealName, "%s", address_displacement(_environment, result->realName, "1") );
155 cpu_math_mul_8bit_to_16bit( _environment, base->realName, resultRealName, temporary->realName, VT_SIGNED( base->type ) );
156 }
157 #else
158 cpu_math_mul_8bit_to_16bit( _environment, base->realName, result->realName, temporary->realName, VT_SIGNED( base->type ) );
159 #endif
160 cpu_move_16bit( _environment, temporary->realName, result->realName );
161 cpu_dec( _environment, counter->realName );
162 cpu_bvneq( _environment, counter->realName, label );
163 cpu_label( _environment, endLabel );
164 break;
165 case 0: {
166 switch( base->type ) {
167 case VT_FLOAT: {
168 result = variable_temporary( _environment, VT_FLOAT, "(result of pow)");
169 temporary = variable_temporary( _environment, VT_FLOAT, "(result of pow)");
170 variable_store_float( _environment, result->name, 1 );
171 cpu_bveq( _environment, counter->realName, endLabel );
172 cpu_label( _environment, label );
173 switch( base->precision ) {
174 case FT_FAST:
175 cpu_float_fast_mul( _environment, base->realName, result->realName, temporary->realName );
176 break;
177 case FT_SINGLE:
178 cpu_float_single_mul( _environment, base->realName, result->realName, temporary->realName );
179 break;
180 default:
182 }
183 variable_move( _environment, temporary->name, result->name );
184 cpu_dec( _environment, counter->realName );
185 cpu_bvneq( _environment, counter->realName, label );
186 cpu_label( _environment, endLabel );
187 break;
188 }
189 default:
190 CRITICAL_POW_UNSUPPORTED( _exponential, DATATYPE_AS_STRING[base->type]);
191 }
192 }
193 }
194 return result;
195}
void cpu_math_mul_16bit_to_32bit(Environment *_environment, char *_source, char *_destination, char *_other, int _signed)
CPU 6309: emit code to multiply two 16 bit values in a 32 bit register
Definition 6309.c:1752
void cpu_bveq(Environment *_environment, char *_value, char *_label)
Definition 6309.c:334
void cpu_move_32bit(Environment *_environment, char *_source, char *_destination)
CPU 6309: emit code to move 32 bit
Definition 6309.c:2520
void cpu_math_mul_8bit_to_16bit(Environment *_environment, char *_source, char *_destination, char *_other, int _signed)
CPU 6309: emit code to multiply two 8bit values in a 16 bit register
Definition 6309.c:1088
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_dec(Environment *_environment, char *_variable)
Definition 6309.c:4630
void cpu_move_16bit(Environment *_environment, char *_source, char *_destination)
CPU 6309: emit code to move 16 bit
Definition 6309.c:1474
void cpu_float_fast_mul(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7207
void cpu_bvneq(Environment *_environment, char *_value, char *_label)
Definition 6309.c:345
void cpu_float_single_mul(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7211
Variable * variable_retrieve(Environment *_environment, char *_name)
Variable * variable_retrieve_or_define(Environment *_environment, char *_name, VariableType _type, int _value)
Variable * variable_move(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable by converting it.
Variable * variable_store_float(Environment *_environment, char *_destination, double _value)
Store a string to a variable.
Variable * variable_cast(Environment *_environment, char *_source, VariableType _type)
Cast a variable from a type to another.
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
Variable * variable_store(Environment *_environment, char *_destination, unsigned int _value)
Store a direct value to a variable.
char * address_displacement(Environment *_environment, char *_address, char *_displacement)
Variable * powering(Environment *_environment, char *_base, char *_exponential)
Emit code to raise a variable to a given variable.
Definition pow.c:91
FloatTypePrecision precision
Definition ugbc.h:991
char * name
Definition ugbc.h:979
VariableType type
Definition ugbc.h:988
char * realName
Definition ugbc.h:982
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define VT_SIGNED(t)
Definition ugbc.h:618
#define CRITICAL_POW_UNSUPPORTED(v, t)
Definition ugbc.h:3475
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_FLOAT
Definition ugbc.h:522
@ VT_WORD
Definition ugbc.h:455
@ VT_POSITION
Definition ugbc.h:468
@ VT_SDWORD
Definition ugbc.h:462
@ VT_SWORD
Definition ugbc.h:457
@ VT_BYTE
Definition ugbc.h:450
@ VT_DWORD
Definition ugbc.h:460
@ VT_SBYTE
Definition ugbc.h:452
#define CRITICAL_CANNOT_CAST(t1, t2)
Definition ugbc.h:3448
@ FT_FAST
Definition ugbc.h:854
@ FT_SINGLE
Definition ugbc.h:855
#define VT_BITWIDTH(t)
Definition ugbc.h:595
#define MAKE_LABEL
Definition ugbc.h:3351
char DATATYPE_AS_STRING[][16]