Skip to content

Commit cb6265d

Browse files
committed
Implemented bitwise operations, began drafting object memory model
1 parent 5a3cd96 commit cb6265d

File tree

9 files changed

+339
-3
lines changed

9 files changed

+339
-3
lines changed

Lang/src/main/java/chipmunk/compiler/assembler/Operands.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,27 @@
2525
public class Operands {
2626

2727
protected Stack<HVMType> types = new Stack<>();
28+
protected final int reserved;
29+
30+
public Operands(){
31+
this(0);
32+
}
33+
34+
public Operands(int reserved){
35+
this.reserved = reserved;
36+
}
2837

2938
public Operand push(HVMType type){
3039
types.push(type);
31-
return new Operand(types.size() - 1, type);
40+
return new Operand(calculateRegister(), type);
3241
}
3342

3443
public Operand pop(){
35-
return new Operand(types.size() - 1, types.pop());
44+
return new Operand(calculateRegister(), types.pop());
45+
}
46+
47+
private int calculateRegister(){
48+
return reserved + types.size() - 1;
3649
}
3750

3851
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (C) 2024 MyWorld, LLC
3+
* All rights reserved.
4+
*
5+
* This file is part of Chipmunk.
6+
*
7+
* Chipmunk is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* Chipmunk is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
package chipmunk.runtime.hvm;
22+
23+
public class CClass {
24+
25+
protected CField[] fields;
26+
protected CField[] shared;
27+
protected CMethod[] methods;
28+
protected long storagePtr;
29+
30+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (C) 2024 MyWorld, LLC
3+
* All rights reserved.
4+
*
5+
* This file is part of Chipmunk.
6+
*
7+
* Chipmunk is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* Chipmunk is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
package chipmunk.runtime.hvm;
22+
23+
public record CField(int offset, int flags, CType pType, String name) {
24+
25+
public int calculateAddress(long pointer){
26+
return (int) pointer + offset;
27+
}
28+
29+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (C) 2024 MyWorld, LLC
3+
* All rights reserved.
4+
*
5+
* This file is part of Chipmunk.
6+
*
7+
* Chipmunk is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* Chipmunk is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
package chipmunk.runtime.hvm;
22+
23+
public class CFlags {
24+
25+
public static final int SHARED = 0b001;
26+
public static final int FINAL = 0b010;
27+
public static final int TRAIT = 0b100;
28+
29+
public static int combine(int... flags){
30+
var combined = 0;
31+
for(var f : flags){
32+
combined |= f;
33+
}
34+
return combined;
35+
}
36+
37+
public static boolean isSet(int flags, int flag){
38+
return (flags & flag) != 0;
39+
}
40+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (C) 2024 MyWorld, LLC
3+
* All rights reserved.
4+
*
5+
* This file is part of Chipmunk.
6+
*
7+
* Chipmunk is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* Chipmunk is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
package chipmunk.runtime.hvm;
22+
23+
public record CMethod(int address, int flags, String name /* TODO - signature*/) {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (C) 2024 MyWorld, LLC
3+
* All rights reserved.
4+
*
5+
* This file is part of Chipmunk.
6+
*
7+
* Chipmunk is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* Chipmunk is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
package chipmunk.runtime.hvm;
22+
23+
public enum CType {
24+
INT(32), LONG(64), FLOAT(32), DOUBLE(64);
25+
private final int width;
26+
27+
CType(int width){
28+
this.width = width;
29+
}
30+
31+
public int bitWidth(){
32+
return width;
33+
}
34+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (C) 2024 MyWorld, LLC
3+
* All rights reserved.
4+
*
5+
* This file is part of Chipmunk.
6+
*
7+
* Chipmunk is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* Chipmunk is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
package chipmunk.runtime.hvm;
22+
23+
import myworld.hummingbird.HummingbirdVM;
24+
25+
public class Memory {
26+
27+
public static long read(long pointer, CType type, HummingbirdVM vm){
28+
return switch (type){
29+
case INT, FLOAT -> vm.memory.getInt((int)pointer);
30+
case LONG, DOUBLE -> vm.memory.getLong((int)pointer);
31+
};
32+
}
33+
34+
public static void write(long pointer, long value, CType type, HummingbirdVM vm){
35+
switch (type){
36+
case INT, FLOAT -> vm.memory.putInt((int) pointer, (int) value);
37+
case LONG, DOUBLE -> vm.memory.putLong((int) pointer, value);
38+
}
39+
}
40+
41+
public static long readField(long pointer, int field, CClass type, HummingbirdVM vm){
42+
var f = type.fields[field];
43+
return read(f.calculateAddress(pointer), f.pType(), vm);
44+
}
45+
46+
public static void writeField(long pointer, long value, int field, CClass type, HummingbirdVM vm){
47+
var f = type.fields[field];
48+
var addr = f.calculateAddress(pointer);
49+
write(f.calculateAddress(addr), value, f.pType(), vm);
50+
}
51+
52+
// TODO - support shared fields in memory model
53+
54+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (C) 2024 MyWorld, LLC
3+
* All rights reserved.
4+
*
5+
* This file is part of Chipmunk.
6+
*
7+
* Chipmunk is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* Chipmunk is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
package chipmunk.runtime.hvm;
22+
23+
public record TypeName(String module, String name) {}

Lang/src/main/java/chipmunk/vm/hvm/HvmCompiler.java

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ public class HvmCompiler {
3737

3838
public ChipmunkModule compileModule(BinaryModule module){
3939
var builder = Executable.builder();
40-
var operands = new Operands();
4140

4241
// For now assume we have a single method with no arguments
4342
module.getNamespace().getEntries().forEach(e -> {
@@ -47,9 +46,13 @@ public ChipmunkModule compileModule(BinaryModule module){
4746
var method = module.getNamespace().getEntries().get(2).getBinaryMethod();
4847
var constants = method.getConstantPool();
4948
var code = method.getCode();
49+
50+
var operands = new Operands(method.getArgCount() + method.getLocalCount());
51+
5052
var ip = 0;
5153
while(ip < code.length){
5254
switch (code[ip]){
55+
// Arithmetic
5356
case PUSH -> ip = push(builder, constants, operands, code, ip);
5457
case ADD -> ip = add(builder, operands, ip);
5558
case MUL -> ip = mul(builder, operands, ip);
@@ -61,6 +64,17 @@ public ChipmunkModule compileModule(BinaryModule module){
6164
case DEC -> ip = dec(builder, operands, ip);
6265
case POS -> ip = pos(builder, operands, ip);
6366
case NEG -> ip = neg(builder, operands, ip);
67+
68+
// Bitwise
69+
case BXOR -> ip = bxor(builder, operands, ip);
70+
case BAND -> ip = band(builder, operands, ip);
71+
case BOR -> ip = bor(builder, operands, ip);
72+
case BNEG -> ip = bneg(builder, operands, ip);
73+
case LSHIFT -> ip = lshift(builder, operands, ip);
74+
case RSHIFT -> ip = rshift(builder, operands, ip);
75+
case URSHIFT -> ip = urshift(builder, operands, ip);
76+
77+
// Flow control
6478
case RETURN -> ip = _return(builder, operands, ip);
6579
default -> {
6680
throw new IllegalArgumentException("Unknown opcode 0x%02X".formatted(code[ip]));
@@ -274,6 +288,82 @@ private int neg(Executable.Builder builder, Operands operands, int ip){
274288
return ip + 1;
275289
}
276290

291+
private int bxor(Executable.Builder builder, Operands operands, int ip){
292+
var b = operands.pop();
293+
var a = operands.pop();
294+
295+
// Disregard operand types - treat everything as a long
296+
builder.appendOpcode(Opcodes.BXOR(a.register(), a.register(), b.register()));
297+
operands.push(LONG);
298+
299+
return ip + 1;
300+
}
301+
302+
private int band(Executable.Builder builder, Operands operands, int ip){
303+
var b = operands.pop();
304+
var a = operands.pop();
305+
306+
// Disregard operand types - treat everything as a long
307+
builder.appendOpcode(Opcodes.BAND(a.register(), a.register(), b.register()));
308+
operands.push(LONG);
309+
310+
return ip + 1;
311+
}
312+
313+
private int bor(Executable.Builder builder, Operands operands, int ip){
314+
var b = operands.pop();
315+
var a = operands.pop();
316+
317+
// Disregard operand types - treat everything as a long
318+
builder.appendOpcode(Opcodes.BOR(a.register(), a.register(), b.register()));
319+
operands.push(LONG);
320+
321+
return ip + 1;
322+
}
323+
324+
private int bneg(Executable.Builder builder, Operands operands, int ip){
325+
var a = operands.pop();
326+
327+
// Disregard operand types - treat everything as a long
328+
builder.appendOpcode(Opcodes.BNOT(a.register(), a.register()));
329+
operands.push(LONG);
330+
331+
return ip + 1;
332+
}
333+
334+
private int lshift(Executable.Builder builder, Operands operands, int ip){
335+
var b = operands.pop();
336+
var a = operands.pop();
337+
338+
// Disregard operand types - treat everything as a long
339+
builder.appendOpcode(Opcodes.BLSHIFT(a.register(), a.register(), b.register()));
340+
operands.push(LONG);
341+
342+
return ip + 1;
343+
}
344+
345+
private int rshift(Executable.Builder builder, Operands operands, int ip){
346+
var b = operands.pop();
347+
var a = operands.pop();
348+
349+
// Disregard operand types - treat everything as a long
350+
builder.appendOpcode(Opcodes.BSRSHIFT(a.register(), a.register(), b.register()));
351+
operands.push(LONG);
352+
353+
return ip + 1;
354+
}
355+
356+
private int urshift(Executable.Builder builder, Operands operands, int ip){
357+
var b = operands.pop();
358+
var a = operands.pop();
359+
360+
// Disregard operand types - treat everything as a long
361+
builder.appendOpcode(Opcodes.BURSHIFT(a.register(), a.register(), b.register()));
362+
operands.push(LONG);
363+
364+
return ip + 1;
365+
}
366+
277367
private int _return(Executable.Builder builder, Operands operands, int ip){
278368
var op = operands.pop();
279369
builder.appendOpcode(Opcodes.RETURN(op.register()));

0 commit comments

Comments
 (0)