Radicalc  Check-in [5bcf572b20]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:added intrinsincs
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:5bcf572b203b5249cb0b00d610c4c6b658db8b3ed0f9def2fc99e43da07d62e8
User & Date: athaudia 2017-08-01 14:16:46
Context
2017-08-01
14:18
added intrinsincs check-in: 863a252f75 user: athaudia tags: trunk
14:16
added intrinsincs check-in: 5bcf572b20 user: athaudia tags: trunk
10:40
split llvm output into seperate .js file check-in: a35ee94f11 user: athaudia tags: trunk
Changes

Changes to src/llvm.js.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
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
..
76
77
78
79
80
81
82









83






84
85
86
87
88
89
90
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
...
234
235
236
237
238
239
240
241
	out.write(fun.dataType.name);
	fun.params.forEach(function(param){
		out.write("__");
		out.write(param.dataType.name);
	});
}

// 1 and not 0 because 0 parses as false, thanks javascript
var llvmVar = 1;
var llvmTmp = 1;
var llvmLabel = 1;

function varStr(v) {
	if(!v.llvmId)
		v.llvmId = llvmVar++;
................................................................................
function newTmp() {
	return "%tmp"+String(llvmTmp++);
}

function newLabel() {
	return "Label"+String(llvmLabel++);
}

function outNode(out, node) {
	switch(node.type) {

		case 'funCall':
			var params = node.params.map(function(param) {
				return [outNode(out, param), param.dataType];


			});






























			var tmp = newTmp();
			out.write("  ");






































			if(node.name == 'add') {
				out.write(tmp);
				out.write(" = add ");
				outDataType(out, params[0][1]);
				out.write(" ");
				out.write(params[0][0]);
				out.write(", ");
				out.write(params[1][0]);
................................................................................
				out.write(" = icmp sle "); //todo: signed vs unsigned
				outDataType(out, params[0][1]);
				out.write(" ");
				out.write(params[0][0]);
				out.write(", ");
				out.write(params[1][0]);
				out.write("\n");









			} else {






				if(node.dataType.name != "void") {
					out.write(tmp);
					out.write(" = ");
				}
				out.write("call ");
				outDataType(out, node.dataType);
				out.write(" ");
................................................................................
		var p = fun.params[i];
		if(i > 0)
			out.write(", ");
		outDataType(out, p.dataType);
		out.write(" ");
		out.write(varStr(p));
	} 
	out.write(")");
	out.write(" {\n");
	outBlock(out, fun.block);
	out.write("}\n\n");
}

function outFunctions(out, funs) {
	funs.forEach(function(fun){
		fun.label = newLabel();
................................................................................
	});
	funs.forEach(function(fun){
		if(!fun.isStub)
			outFunction(out, fun);
	});
}

module.exports = {outFunctions: outFunctions};







|







 








|
<
>
|
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







>
>
>
>
>
>
>
>
>

>
>
>
>
>
>







 







|
<







 







|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
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
...
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
...
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
...
317
318
319
320
321
322
323
324
	out.write(fun.dataType.name);
	fun.params.forEach(function(param){
		out.write("__");
		out.write(param.dataType.name);
	});
}

// 1 and not 0 because 0 parses as false
var llvmVar = 1;
var llvmTmp = 1;
var llvmLabel = 1;

function varStr(v) {
	if(!v.llvmId)
		v.llvmId = llvmVar++;
................................................................................
function newTmp() {
	return "%tmp"+String(llvmTmp++);
}

function newLabel() {
	return "Label"+String(llvmLabel++);
}

var llvmIntrinsics = [];


function addIntrinsic(name, dataTypes, func) {
	llvmIntrinsics.push({
		name: name,
		dataTypes: dataTypes,
		func: func	
	});
}

function getIntrinsic(name, dataTypes) {
	for(var i = 0; i < llvmIntrinsics.length; ++i) {
		var int = llvmIntrinsics[i];
		if(name == int.name && dataTypes.length == int.dataTypes.length) {
			var pe = true;
			for(var j = 0; j < dataTypes.length; ++j)
				pe = pe && (dataTypes[j] == int.dataTypes[j]);
			if(pe)
				return int.func;
		}
	}
	return false;
}

const icmpOp = {
	"is_less": "slt",
	"is_less_or_eq": "sle",
	"is_greater": "sgt",
	"is_greater_or_eq": "sge",
	"is_eq": "eq",
	"is_not_eq": "ne"
};

function initIntrinsics(dataTypes) {
	["add", "sub", "mul", "div"].forEach((op) => {
		[dataTypes.i8, dataTypes.i16,
		dataTypes.i32, dataTypes.i64].forEach((dt) => {
			addIntrinsic(op, [dt,dt], (out, params) => {
				var tmp = newTmp();
				out.write("  " + tmp + " = " + op + " ");
				outDataType(out, dt);
				out.write(" " + params[0] + ", " + params[1] + "\n")
				return tmp;
			});
		});
	});

	["is_less", "is_less_or_eq",
	"is_greater", "is_greater_or_eq"].forEach((op) => {
		[dataTypes.i8, dataTypes.i16,
		dataTypes.i32, dataTypes.i64].forEach((dt) => {
			addIntrinsic(op, [dt, dt], (out, params) => {
				var tmp = newTmp();
				out.write("  " + tmp + " = icmp " + icmpOp[op] + " ");
				outDataType(out, dt);
				out.write(" " + params[0] + ", " + params[1] + "\n");
				return tmp;
			});
		});
	});

	["is_eq", "is_not_eq"].forEach((op) => {
		[dataTypes.i8, dataTypes.i16, dataTypes.i32, dataTypes.i64,
		dataTypes.bool].forEach((dt) => {
			addIntrinsic(op, [dt, dt], (out, params) => {
				var tmp = newTmp();
				out.write("  " + tmp + " = icmp "+ icmpOp[op] + " ");
				outDataType(out, dt);
				out.write(" " + params[0] + ", " + params[1] + "\n");
				return tmp;
			});
		});
	});
}

function outNode(out, node) {
	switch(node.type) {
		case 'funCall':
			/*if(node.name == 'add') {
				out.write(tmp);
				out.write(" = add ");
				outDataType(out, params[0][1]);
				out.write(" ");
				out.write(params[0][0]);
				out.write(", ");
				out.write(params[1][0]);
................................................................................
				out.write(" = icmp sle "); //todo: signed vs unsigned
				outDataType(out, params[0][1]);
				out.write(" ");
				out.write(params[0][0]);
				out.write(", ");
				out.write(params[1][0]);
				out.write("\n");
			} else */

			var dts = node.params.map((param) => { return param.dataType });
			var intrinsicFunc = getIntrinsic(node.name, dts);
			if(intrinsicFunc) {
				var params = node.params.map((param) => {
					return outNode(out, param);
				});
				return intrinsicFunc(out, params);
			} else {
				var params = node.params.map(function(param) {
					return [outNode(out, param), param.dataType];
				});
				var tmp = newTmp();
				out.write("  ");
			
				if(node.dataType.name != "void") {
					out.write(tmp);
					out.write(" = ");
				}
				out.write("call ");
				outDataType(out, node.dataType);
				out.write(" ");
................................................................................
		var p = fun.params[i];
		if(i > 0)
			out.write(", ");
		outDataType(out, p.dataType);
		out.write(" ");
		out.write(varStr(p));
	} 
	out.write(") {\n");

	outBlock(out, fun.block);
	out.write("}\n\n");
}

function outFunctions(out, funs) {
	funs.forEach(function(fun){
		fun.label = newLabel();
................................................................................
	});
	funs.forEach(function(fun){
		if(!fun.isStub)
			outFunction(out, fun);
	});
}

module.exports = {outFunctions: outFunctions, initIntrinsics: initIntrinsics};

Changes to src/radicalc.js.

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

////////////////////////////////////////

initFunctionScopes();
preAnnotate();
annotateFunctions();


var out = fs.createWriteStream("tmp.ll");
llvm.outFunctions(out, funs);
//llvm.outFunctions(process.stdout, funs);
out.end();

exec('opt -O3 tmp.ll -S -o tmp.s && llc tmp.s -o tmp.o -filetype=obj && lld-link tmp.o /entry:main__i32 /subsystem:console && test2.bat', (error, stdout, stderr) => {
  if (error) {
................................................................................
  	console.error(`exec error: ${error}`);
  	return;
  }
  console.log(stdout);
});

/* todo:
 - implement add, sub, div, mul and relational operators correctly
   - check signedness
 - seperate into multiple files
 - figure out how to link against standard functions

*/







>







 







|
<
<

>

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

////////////////////////////////////////

initFunctionScopes();
preAnnotate();
annotateFunctions();

llvm.initIntrinsics(dataTypes);
var out = fs.createWriteStream("tmp.ll");
llvm.outFunctions(out, funs);
//llvm.outFunctions(process.stdout, funs);
out.end();

exec('opt -O3 tmp.ll -S -o tmp.s && llc tmp.s -o tmp.o -filetype=obj && lld-link tmp.o /entry:main__i32 /subsystem:console && test2.bat', (error, stdout, stderr) => {
  if (error) {
................................................................................
  	console.error(`exec error: ${error}`);
  	return;
  }
  console.log(stdout);
});

/* todo:
 - unsigned intrinsics


 - figure out how to link against standard functions
 - strings?
*/