aboutsummaryrefslogtreecommitdiff
path: root/src/parseTools.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/parseTools.js')
-rw-r--r--src/parseTools.js96
1 files changed, 43 insertions, 53 deletions
diff --git a/src/parseTools.js b/src/parseTools.js
index dae386f1..ec907a41 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -157,6 +157,10 @@ function isStructType(type) {
return type[0] == '%';
}
+function isVectorType(type) {
+ return type[type.length-1] === '>';
+}
+
function isStructuralType(type) {
return /^{ ?[^}]* ?}$/.test(type); // { i32, i8 } etc. - anonymous struct types
}
@@ -215,8 +219,22 @@ function isIdenticallyImplemented(type1, type2) {
}
function isIllegalType(type) {
- var bits = getBits(type);
- return bits > 0 && (bits >= 64 || !isPowerOfTwo(bits));
+ switch (type) {
+ case 'i1':
+ case 'i8':
+ case 'i16':
+ case 'i32':
+ case 'float':
+ case 'double':
+ case 'rawJS':
+ case '<2 x float>':
+ case '<4 x float>':
+ case '<2 x i32>':
+ case '<4 x i32>':
+ case 'void': return false;
+ }
+ if (!type || type[type.length-1] === '*') return false;
+ return true;
}
function isVoidType(type) {
@@ -287,6 +305,9 @@ function getReturnType(type) {
if (pointingLevels(type) > 1) return '*'; // the type of a call can be either the return value, or the entire function. ** or more means it is a return value
var lastOpen = type.lastIndexOf('(');
if (lastOpen > 0) {
+ // handle things like void (i32)* (i32, void (i32)*)*
+ var closeStar = type.indexOf(')*');
+ if (closeStar > 0 && closeStar < type.length-2) lastOpen = closeStar+3;
return type.substr(0, lastOpen-1);
}
return type;
@@ -328,28 +349,29 @@ function getVectorSize(type) {
return parseInt(type.substring(1, type.indexOf(' ')));
}
-function getVectorBaseType(type) {
+function getVectorNativeType(type) {
Types.usesSIMD = true;
switch (type) {
case '<2 x float>':
case '<4 x float>': return 'float';
case '<2 x i32>':
- case '<4 x i32>': return 'uint';
+ case '<4 x i32>': return 'i32';
default: throw 'unknown vector type ' + type;
}
}
-function getVectorNativeType(type) {
- Types.usesSIMD = true;
+function getSIMDName(type) {
switch (type) {
- case '<2 x float>':
- case '<4 x float>': return 'float';
- case '<2 x i32>':
- case '<4 x i32>': return 'i32';
- default: throw 'unknown vector type ' + type;
+ case 'i32': return 'uint';
+ case 'float': return 'float';
+ default: throw 'getSIMDName ' + type;
}
}
+function getVectorBaseType(type) {
+ return getSIMDName(getVectorNativeType(type));
+}
+
function addIdent(token) {
token.ident = token.text;
return token;
@@ -465,26 +487,13 @@ function parseParamTokens(params) {
Types.needAnalysis[ret[ret.length-1].type] = 0;
anonymousIndex ++;
}
- } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) {
- ret.push(parseLLVMFunctionCall(segment));
- } else if (segment[1].text === 'blockaddress') {
- ret.push(parseBlockAddress(segment));
- } else if (segment[1].type && segment[1].type == '{') {
- ret.push(parseLLVMSegment(segment));
} else {
if (segment[2] && segment[2].text == 'to') { // part of bitcast params
segment = segment.slice(0, 2);
}
- while (segment.length > 2) {
- segment[0].text += segment[1].text;
- segment.splice(1, 1); // TODO: merge tokens nicely
- }
- ret.push({
- intertype: 'value',
- type: segment[0].text,
- ident: toNiceIdent(parseNumerical(segment[1].text, segment[0].text))
- });
- Types.needAnalysis[removeAllPointing(ret[ret.length-1].type)] = 0;
+ var parsed = parseLLVMSegment(segment);
+ if (parsed.intertype === 'value' && !isIllegalType(parsed.type)) parsed.ident = parseNumerical(parsed.ident, parsed.type);
+ ret.push(parsed);
}
ret[ret.length-1].byVal = byVal;
}
@@ -558,25 +567,6 @@ function sortGlobals(globals) {
});
}
-function finalizeParam(param) {
- if (param.intertype in PARSABLE_LLVM_FUNCTIONS) {
- return finalizeLLVMFunctionCall(param);
- } else if (param.intertype === 'blockaddress') {
- return finalizeBlockAddress(param);
- } else if (param.intertype === 'jsvalue') {
- return param.ident;
- } else {
- if (param.type == 'i64' && USE_TYPED_ARRAYS == 2) {
- return parseI64Constant(param.ident);
- }
- var ret = toNiceIdent(param.ident);
- if (ret in Variables.globals) {
- ret = makeGlobalUse(ret);
- }
- return ret;
- }
-}
-
// Segment ==> Parameter
function parseLLVMSegment(segment) {
var type;
@@ -1009,11 +999,9 @@ function getOldLabel(label) {
}
function calcAllocatedSize(type) {
- if (pointingLevels(type) == 0 && isStructType(type)) {
- return Types.types[type].flatSize; // makeEmptyStruct(item.allocatedType).length;
- } else {
- return Runtime.getNativeTypeSize(type); // We can really get away with '1', though, at least on the stack...
- }
+ var ret = Runtime.getNativeTypeSize(type);
+ if (ret) return ret;
+ return Types.types[type].flatSize; // known type
}
// Generates the type signature for a structure, for each byte, the type that is there.
@@ -1809,7 +1797,7 @@ function makeGetSlabs(ptr, type, allowMultiple, unsigned) {
switch(type) {
case 'i1': case 'i8': return [unsigned ? 'HEAPU8' : 'HEAP8']; break;
case 'i16': return [unsigned ? 'HEAPU16' : 'HEAP16']; break;
- case '<4 x i32>': case 'uint':
+ case '<4 x i32>':
case 'i32': case 'i64': return [unsigned ? 'HEAPU32' : 'HEAP32']; break;
case 'double': {
if (TARGET_LE32) return ['HEAPF64']; // in le32, we do have the ability to assume 64-bit alignment
@@ -2002,6 +1990,8 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) {
} else if (param.ident == 'zeroinitializer') {
if (isStructType(param.type)) {
return makeLLVMStruct(zeros(Types.types[param.type].fields.length));
+ } else if (isVectorType(param.type)) {
+ return ensureVector(0, getVectorBaseType(param.type));
} else {
return '0';
}
@@ -2024,7 +2014,7 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) {
} else if (param.intertype == 'mathop') {
return processMathop(param);
} else if (param.intertype === 'vector') {
- return 'float32x4(' + param.idents.join(',') + ')';
+ return getVectorBaseType(param.type) + '32x4(' + param.idents.join(',') + ')';
} else {
throw 'invalid llvm parameter: ' + param.intertype;
}