2 * Copyright 2010-2012 Chris Spiegel.
4 * This file is part of Bocfel.
6 * Bocfel is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version
8 * 2 or 3, as published by the Free Software Foundation.
10 * Bocfel is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Bocfel. If not, see <http://www.gnu.org/licenses/>.
30 store_variable(zargs[0], variable(zargs[0]) + 1);
35 store_variable(zargs[0], variable(zargs[0]) - 1);
46 int16_t val = zargs[1];
50 /* The z-spec 1.1 requires indirect variable references to the stack not to push/pop */
51 if(zargs[0] == 0) new = *stack_top_element();
52 else new = variable(zargs[0]);
60 int16_t val = zargs[1];
64 /* The z-spec 1.1 requires indirect variable references to the stack not to push/pop */
65 if(zargs[0] == 0) new = *stack_top_element();
66 else new = variable(zargs[0]);
73 branch_if( (zargs[0] & zargs[1]) == zargs[1] );
78 store(zargs[0] | zargs[1]);
83 store(zargs[0] & zargs[1]);
88 store(zargs[0] + zargs[1]);
93 store(zargs[0] - zargs[1]);
98 store(zargs[0] * zargs[1]);
103 ZASSERT(zargs[1] != 0, "divide by zero");
104 store((int16_t)zargs[0] / (int16_t)zargs[1]);
109 ZASSERT(zargs[1] != 0, "divide by zero");
110 store((int16_t)zargs[0] % (int16_t)zargs[1]);
113 void zlog_shift(void)
115 int16_t places = zargs[1];
117 /* Shifting more than 15 bits is undefined (as of Standard 1.1), but
118 * do the most sensible thing.
120 if(places < -15 || places > 15)
126 if(places < 0) store(zargs[0] >> -places);
127 else store(zargs[0] << places);
130 void zart_shift(void)
132 int16_t number = zargs[0], places = zargs[1];
134 /* Shifting more than 15 bits is undefined (as of Standard 1.1), but
135 * do the most sensible thing.
137 if(places < -15 || places > 15)
139 store(number < 0 ? -1 : 0);
143 /* Shifting a negative value in C has some consequences:
144 * • Shifting a negative value left is undefined.
145 * • Shifting a negative value right is implementation defined.
147 * Thus these are done by hand. The Z-machine requires a right-shift
148 * of a negative value to propagate the sign bit. This is easily
149 * accomplished by complementing the value (yielding a positive
150 * number), shifting it right (zero filling), and complementing again
151 * (flip the shifted-in zeroes to ones).
153 * For a left-shift, the result should presumably be the same as a
154 * logical shift, so do that.
158 if(places < 0) store(~(~number >> -places));
159 else store(zargs[0] << places);
163 if(places < 0) store(zargs[0] >> -places);
164 else store(zargs[0] << places);