1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
|
#include "stdafx.h"
#include "Long.h"
#include "Core/Array.h"
#include "Core/Hash.h"
#include "Core/Str.h"
#include "Core/Io/Serialization.h"
#include "Core/Io/SerializationUtils.h"
#include "Function.h"
#include "Number.h"
namespace storm {
using namespace code;
Type *createLong(Str *name, Size size, GcType *type) {
return new (name) LongType(name, type);
}
// Note: Works for both float and double.
static void longToFloat(InlineParams p) {
if (!p.result->needed())
return;
*p.state->l << icastf(p.result->location(p.state), p.param(0));
}
static void castLong(InlineParams p) {
p.allocRegs(0);
*p.state->l << icast(longRel(p.regParam(0), Offset()), p.param(1));
}
static Long longRead(IStream *from) {
return from->readLong();
}
static Long longReadS(ObjIStream *from) {
return Serialize<Long>::read(from);
}
static void longWrite(Long v, OStream *to) {
to->writeLong(v);
}
static void longWriteS(Long v, ObjOStream *to) {
Serialize<Long>::write(v, to);
}
static void longToS(Long &v, StrBuf *to) {
*to << v;
}
LongType::LongType(Str *name, GcType *type) : Type(name, typeValue | typeFinal, Size::sLong, type, null) {}
Bool LongType::loadAll() {
Array<Value> *r = new (this) Array<Value>(1, Value(this, true));
Array<Value> *rr = new (this) Array<Value>(2, Value(this, true));
Array<Value> *v = new (this) Array<Value>(1, Value(this, false));
Array<Value> *vv = new (this) Array<Value>(2, Value(this, false));
Array<Value> *rv = new (this) Array<Value>(2, Value(this, true));
rv->at(1) = Value(this);
Value b(StormInfo<Bool>::type(engine));
add(inlinedFunction(engine, Value(this), S("+"), vv, fnPtr(engine, &numAdd))->makePure());
add(inlinedFunction(engine, Value(this), S("-"), vv, fnPtr(engine, &numSub))->makePure());
add(inlinedFunction(engine, Value(this), S("*"), vv, fnPtr(engine, &numMul))->makePure());
add(inlinedFunction(engine, Value(this), S("/"), vv, fnPtr(engine, &numIDiv))->makePure());
add(inlinedFunction(engine, Value(this), S("%"), vv, fnPtr(engine, &numIMod))->makePure());
add(inlinedFunction(engine, Value(this), S("-"), v, fnPtr(engine, &numINeg))->makePure());
add(inlinedFunction(engine, b, S("=="), vv, fnPtr(engine, &numCmp<ifEqual>))->makePure());
add(inlinedFunction(engine, b, S("!="), vv, fnPtr(engine, &numCmp<ifNotEqual>))->makePure());
add(inlinedFunction(engine, b, S("<="), vv, fnPtr(engine, &numCmp<ifLessEqual>))->makePure());
add(inlinedFunction(engine, b, S(">="), vv, fnPtr(engine, &numCmp<ifGreaterEqual>))->makePure());
add(inlinedFunction(engine, b, S("<"), vv, fnPtr(engine, &numCmp<ifLess>))->makePure());
add(inlinedFunction(engine, b, S(">"), vv, fnPtr(engine, &numCmp<ifGreater>))->makePure());
add(inlinedFunction(engine, Value(this), S("*++"), r, fnPtr(engine, &numPostfixInc<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("++*"), r, fnPtr(engine, &numPrefixInc<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("*--"), r, fnPtr(engine, &numPostfixDec<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("--*"), r, fnPtr(engine, &numPrefixDec<Long>))->makePure());
add(inlinedFunction(engine, Value(this, true), S("="), rv, fnPtr(engine, &numAssign<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("+="), rv, fnPtr(engine, &numInc<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("-="), rv, fnPtr(engine, &numDec<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("*="), rv, fnPtr(engine, &numScale<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("/="), rv, fnPtr(engine, &numIDivScale<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("%="), rv, fnPtr(engine, &numIModEq<Long>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, rr, fnPtr(engine, &numCopyCtor<Long>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, r, fnPtr(engine, &numInit<Long>))->makePure());
Array<Value> *ri = valList(engine, 2, Value(this, true), Value(StormInfo<Int>::type(engine)));
add(inlinedFunction(engine, Value(), Type::CTOR, ri, fnPtr(engine, &castLong))->makeAutoCast()->makePure());
add(inlinedFunction(engine, Value(StormInfo<Int>::type(engine)), S("int"), v, fnPtr(engine, &icast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Nat>::type(engine)), S("nat"), v, fnPtr(engine, &icast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Byte>::type(engine)), S("byte"), v, fnPtr(engine, &icast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Word>::type(engine)), S("word"), v, fnPtr(engine, &icast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Float>::type(engine)), S("float"), v, fnPtr(engine, &longToFloat))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Double>::type(engine)), S("double"), v, fnPtr(engine, &longToFloat))->makePure());
Value n(StormInfo<Nat>::type(engine));
add(nativeFunction(engine, n, S("hash"), v, address(&longHash))->makePure());
add(inlinedFunction(engine, Value(this), S("min"), vv, fnPtr(engine, &numMin<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("max"), vv, fnPtr(engine, &numMax<Long>))->makePure());
add(inlinedFunction(engine, Value(this), S("delta"), vv, fnPtr(engine, &numDelta<Long>))->makePure());
Array<Value> *rs = new (this) Array<Value>(2, Value(this, true));
rs->at(1) = StormInfo<StrBuf>::type(engine);
add(nativeFunction(engine, Value(), S("toS"), rs, address(&longToS)));
Array<Value> *is = new (this) Array<Value>(1, Value(StormInfo<IStream>::type(engine)));
add(nativeFunction(engine, Value(this), S("read"), is, address(&longRead)));
is = new (this) Array<Value>(1, Value(StormInfo<ObjIStream>::type(engine)));
add(nativeFunction(engine, Value(this), S("read"), is, address(&longReadS)));
Array<Value> *os = new (this) Array<Value>(2, Value(this, false));
os->at(1) = Value(StormInfo<OStream>::type(engine));
add(nativeFunction(engine, Value(), S("write"), os, address(&longWrite)));
os = new (this) Array<Value>(2, Value(this, false));
os->at(1) = Value(StormInfo<ObjOStream>::type(engine));
add(nativeFunction(engine, Value(), S("write"), os, address(&longWriteS)));
return Type::loadAll();
}
Type *createWord(Str *name, Size size, GcType *type) {
return new (name) WordType(name, type);
}
static void castWord(InlineParams p) {
p.allocRegs(0);
*p.state->l << ucast(longRel(p.regParam(0), Offset()), p.param(1));
}
static void wordToFloat(InlineParams p) {
if (!p.result->needed())
return;
*p.state->l << ucastf(p.result->location(p.state), p.param(0));
}
static Word wordRead(IStream *from) {
return from->readWord();
}
static Word wordReadS(ObjIStream *from) {
return Serialize<Word>::read(from);
}
static void wordWrite(Word v, OStream *to) {
to->writeWord(v);
}
static void wordWriteS(Word v, ObjOStream *to) {
Serialize<Word>::write(v, to);
}
static void wordToS(Word &v, StrBuf *to) {
*to << v;
}
WordType::WordType(Str *name, GcType *type) : Type(name, typeValue | typeFinal, Size::sWord, type, null) {}
Bool WordType::loadAll() {
Array<Value> *r = new (this) Array<Value>(1, Value(this, true));
Array<Value> *rr = new (this) Array<Value>(2, Value(this, true));
Array<Value> *v = new (this) Array<Value>(1, Value(this, false));
Array<Value> *vv = new (this) Array<Value>(2, Value(this, false));
Array<Value> *rv = new (this) Array<Value>(2, Value(this, true));
rv->at(1) = Value(this);
Value b(StormInfo<Bool>::type(engine));
Array<Value> *vb = new (this) Array<Value>(2, Value(this, false));
Array<Value> *rb = new (this) Array<Value>(2, Value(this, true));
vb->at(1) = rb->at(1) = Value(StormInfo<Byte>::type(engine));
add(inlinedFunction(engine, Value(this), S("+"), vv, fnPtr(engine, &numAdd))->makePure());
add(inlinedFunction(engine, Value(this), S("-"), vv, fnPtr(engine, &numSub))->makePure());
add(inlinedFunction(engine, Value(this), S("*"), vv, fnPtr(engine, &numMul))->makePure());
add(inlinedFunction(engine, Value(this), S("/"), vv, fnPtr(engine, &numUDiv))->makePure());
add(inlinedFunction(engine, Value(this), S("%"), vv, fnPtr(engine, &numUMod))->makePure());
add(inlinedFunction(engine, b, S("=="), vv, fnPtr(engine, &numCmp<ifEqual>))->makePure());
add(inlinedFunction(engine, b, S("!="), vv, fnPtr(engine, &numCmp<ifNotEqual>))->makePure());
add(inlinedFunction(engine, b, S("<="), vv, fnPtr(engine, &numCmp<ifBelowEqual>))->makePure());
add(inlinedFunction(engine, b, S(">="), vv, fnPtr(engine, &numCmp<ifAboveEqual>))->makePure());
add(inlinedFunction(engine, b, S("<"), vv, fnPtr(engine, &numCmp<ifBelow>))->makePure());
add(inlinedFunction(engine, b, S(">"), vv, fnPtr(engine, &numCmp<ifAbove>))->makePure());
add(inlinedFunction(engine, Value(this), S("*++"), r, fnPtr(engine, &numPostfixInc<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("++*"), r, fnPtr(engine, &numPrefixInc<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("*--"), r, fnPtr(engine, &numPostfixDec<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("--*"), r, fnPtr(engine, &numPrefixDec<Word>))->makePure());
add(inlinedFunction(engine, Value(this, true), S("="), rv, fnPtr(engine, &numAssign<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("+="), rv, fnPtr(engine, &numInc<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("-="), rv, fnPtr(engine, &numDec<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("*="), rv, fnPtr(engine, &numScale<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("/="), rv, fnPtr(engine, &numUDivScale<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("%="), rv, fnPtr(engine, &numUModEq<Word>))->makePure());
// Bitwise operators.
add(inlinedFunction(engine, Value(this), S("&"), vv, fnPtr(engine, &numAnd))->makePure());
add(inlinedFunction(engine, Value(this), S("|"), vv, fnPtr(engine, &numOr))->makePure());
add(inlinedFunction(engine, Value(this), S("^"), vv, fnPtr(engine, &numXor))->makePure());
add(inlinedFunction(engine, Value(this), S("~"), v, fnPtr(engine, &numNot))->makePure());
add(inlinedFunction(engine, Value(this), S("<<"), vb, fnPtr(engine, &numShl))->makePure());
add(inlinedFunction(engine, Value(this), S(">>"), vb, fnPtr(engine, &numShr))->makePure());
add(inlinedFunction(engine, Value(this), S("&="), rv, fnPtr(engine, &numAndEq<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("|="), rv, fnPtr(engine, &numOrEq<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("^="), rv, fnPtr(engine, &numXorEq<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("<<="), rb, fnPtr(engine, &numShlEq<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S(">>="), rb, fnPtr(engine, &numShrEq<Word>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, rr, fnPtr(engine, &numCopyCtor<Word>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, r, fnPtr(engine, &numInit<Word>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, rb, fnPtr(engine, &castWord))->makeAutoCast()->makePure());
Array<Value> *ri = valList(engine, 2, Value(this, true), Value(StormInfo<Nat>::type(engine)));
add(inlinedFunction(engine, Value(), Type::CTOR, ri, fnPtr(engine, &castWord))->makeAutoCast()->makePure());
add(inlinedFunction(engine, Value(StormInfo<Int>::type(engine)), S("int"), v, fnPtr(engine, &ucast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Nat>::type(engine)), S("nat"), v, fnPtr(engine, &ucast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Byte>::type(engine)), S("byte"), v, fnPtr(engine, &ucast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Long>::type(engine)), S("long"), v, fnPtr(engine, &ucast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Float>::type(engine)), S("float"), v, fnPtr(engine, &wordToFloat))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Double>::type(engine)), S("double"), v, fnPtr(engine, &wordToFloat))->makePure());
Value n(StormInfo<Nat>::type(engine));
add(nativeFunction(engine, n, S("hash"), v, address(&wordHash))->makePure());
add(inlinedFunction(engine, Value(this), S("min"), vv, fnPtr(engine, &numMin<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("max"), vv, fnPtr(engine, &numMax<Word>))->makePure());
add(inlinedFunction(engine, Value(this), S("delta"), vv, fnPtr(engine, &numDelta<Word>))->makePure());
Array<Value> *rs = new (this) Array<Value>(2, Value(this, true));
rs->at(1) = StormInfo<StrBuf>::type(engine);
add(nativeFunction(engine, Value(), S("toS"), rs, address(&wordToS)));
Array<Value> *is = new (this) Array<Value>(1, Value(StormInfo<IStream>::type(engine)));
add(nativeFunction(engine, Value(this), S("read"), is, address(&wordRead)));
is = new (this) Array<Value>(1, Value(StormInfo<ObjIStream>::type(engine)));
add(nativeFunction(engine, Value(this), S("read"), is, address(&wordReadS)));
Array<Value> *os = new (this) Array<Value>(2, Value(this, false));
os->at(1) = Value(StormInfo<OStream>::type(engine));
add(nativeFunction(engine, Value(), S("write"), os, address(&wordWrite)));
os = new (this) Array<Value>(2, Value(this, false));
os->at(1) = Value(StormInfo<ObjOStream>::type(engine));
add(nativeFunction(engine, Value(), S("write"), os, address(&wordWriteS)));
return Type::loadAll();
}
}
|