Skip to content

Commit

Permalink
Implemented bitwise operations, began drafting object memory model
Browse files Browse the repository at this point in the history
  • Loading branch information
danielperano committed Dec 21, 2024
1 parent 5a3cd96 commit cb6265d
Show file tree
Hide file tree
Showing 9 changed files with 339 additions and 3 deletions.
17 changes: 15 additions & 2 deletions Lang/src/main/java/chipmunk/compiler/assembler/Operands.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,27 @@
public class Operands {

protected Stack<HVMType> types = new Stack<>();
protected final int reserved;

public Operands(){
this(0);
}

public Operands(int reserved){
this.reserved = reserved;
}

public Operand push(HVMType type){
types.push(type);
return new Operand(types.size() - 1, type);
return new Operand(calculateRegister(), type);
}

public Operand pop(){
return new Operand(types.size() - 1, types.pop());
return new Operand(calculateRegister(), types.pop());
}

private int calculateRegister(){
return reserved + types.size() - 1;
}

}
30 changes: 30 additions & 0 deletions Lang/src/main/java/chipmunk/runtime/hvm/CClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2024 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.runtime.hvm;

public class CClass {

protected CField[] fields;
protected CField[] shared;
protected CMethod[] methods;
protected long storagePtr;

}
29 changes: 29 additions & 0 deletions Lang/src/main/java/chipmunk/runtime/hvm/CField.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.runtime.hvm;

public record CField(int offset, int flags, CType pType, String name) {

public int calculateAddress(long pointer){
return (int) pointer + offset;
}

}
40 changes: 40 additions & 0 deletions Lang/src/main/java/chipmunk/runtime/hvm/CFlags.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2024 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.runtime.hvm;

public class CFlags {

public static final int SHARED = 0b001;
public static final int FINAL = 0b010;
public static final int TRAIT = 0b100;

public static int combine(int... flags){
var combined = 0;
for(var f : flags){
combined |= f;
}
return combined;
}

public static boolean isSet(int flags, int flag){
return (flags & flag) != 0;
}
}
23 changes: 23 additions & 0 deletions Lang/src/main/java/chipmunk/runtime/hvm/CMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2024 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.runtime.hvm;

public record CMethod(int address, int flags, String name /* TODO - signature*/) {}
34 changes: 34 additions & 0 deletions Lang/src/main/java/chipmunk/runtime/hvm/CType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2024 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.runtime.hvm;

public enum CType {
INT(32), LONG(64), FLOAT(32), DOUBLE(64);
private final int width;

CType(int width){
this.width = width;
}

public int bitWidth(){
return width;
}
}
54 changes: 54 additions & 0 deletions Lang/src/main/java/chipmunk/runtime/hvm/Memory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2024 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.runtime.hvm;

import myworld.hummingbird.HummingbirdVM;

public class Memory {

public static long read(long pointer, CType type, HummingbirdVM vm){
return switch (type){
case INT, FLOAT -> vm.memory.getInt((int)pointer);
case LONG, DOUBLE -> vm.memory.getLong((int)pointer);
};
}

public static void write(long pointer, long value, CType type, HummingbirdVM vm){
switch (type){
case INT, FLOAT -> vm.memory.putInt((int) pointer, (int) value);
case LONG, DOUBLE -> vm.memory.putLong((int) pointer, value);
}
}

public static long readField(long pointer, int field, CClass type, HummingbirdVM vm){
var f = type.fields[field];
return read(f.calculateAddress(pointer), f.pType(), vm);
}

public static void writeField(long pointer, long value, int field, CClass type, HummingbirdVM vm){
var f = type.fields[field];
var addr = f.calculateAddress(pointer);
write(f.calculateAddress(addr), value, f.pType(), vm);
}

// TODO - support shared fields in memory model

}
23 changes: 23 additions & 0 deletions Lang/src/main/java/chipmunk/runtime/hvm/TypeName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2024 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.runtime.hvm;

public record TypeName(String module, String name) {}
92 changes: 91 additions & 1 deletion Lang/src/main/java/chipmunk/vm/hvm/HvmCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public class HvmCompiler {

public ChipmunkModule compileModule(BinaryModule module){
var builder = Executable.builder();
var operands = new Operands();

// For now assume we have a single method with no arguments
module.getNamespace().getEntries().forEach(e -> {
Expand All @@ -47,9 +46,13 @@ public ChipmunkModule compileModule(BinaryModule module){
var method = module.getNamespace().getEntries().get(2).getBinaryMethod();
var constants = method.getConstantPool();
var code = method.getCode();

var operands = new Operands(method.getArgCount() + method.getLocalCount());

var ip = 0;
while(ip < code.length){
switch (code[ip]){
// Arithmetic
case PUSH -> ip = push(builder, constants, operands, code, ip);
case ADD -> ip = add(builder, operands, ip);
case MUL -> ip = mul(builder, operands, ip);
Expand All @@ -61,6 +64,17 @@ public ChipmunkModule compileModule(BinaryModule module){
case DEC -> ip = dec(builder, operands, ip);
case POS -> ip = pos(builder, operands, ip);
case NEG -> ip = neg(builder, operands, ip);

// Bitwise
case BXOR -> ip = bxor(builder, operands, ip);
case BAND -> ip = band(builder, operands, ip);
case BOR -> ip = bor(builder, operands, ip);
case BNEG -> ip = bneg(builder, operands, ip);
case LSHIFT -> ip = lshift(builder, operands, ip);
case RSHIFT -> ip = rshift(builder, operands, ip);
case URSHIFT -> ip = urshift(builder, operands, ip);

// Flow control
case RETURN -> ip = _return(builder, operands, ip);
default -> {
throw new IllegalArgumentException("Unknown opcode 0x%02X".formatted(code[ip]));
Expand Down Expand Up @@ -274,6 +288,82 @@ private int neg(Executable.Builder builder, Operands operands, int ip){
return ip + 1;
}

private int bxor(Executable.Builder builder, Operands operands, int ip){
var b = operands.pop();
var a = operands.pop();

// Disregard operand types - treat everything as a long
builder.appendOpcode(Opcodes.BXOR(a.register(), a.register(), b.register()));
operands.push(LONG);

return ip + 1;
}

private int band(Executable.Builder builder, Operands operands, int ip){
var b = operands.pop();
var a = operands.pop();

// Disregard operand types - treat everything as a long
builder.appendOpcode(Opcodes.BAND(a.register(), a.register(), b.register()));
operands.push(LONG);

return ip + 1;
}

private int bor(Executable.Builder builder, Operands operands, int ip){
var b = operands.pop();
var a = operands.pop();

// Disregard operand types - treat everything as a long
builder.appendOpcode(Opcodes.BOR(a.register(), a.register(), b.register()));
operands.push(LONG);

return ip + 1;
}

private int bneg(Executable.Builder builder, Operands operands, int ip){
var a = operands.pop();

// Disregard operand types - treat everything as a long
builder.appendOpcode(Opcodes.BNOT(a.register(), a.register()));
operands.push(LONG);

return ip + 1;
}

private int lshift(Executable.Builder builder, Operands operands, int ip){
var b = operands.pop();
var a = operands.pop();

// Disregard operand types - treat everything as a long
builder.appendOpcode(Opcodes.BLSHIFT(a.register(), a.register(), b.register()));
operands.push(LONG);

return ip + 1;
}

private int rshift(Executable.Builder builder, Operands operands, int ip){
var b = operands.pop();
var a = operands.pop();

// Disregard operand types - treat everything as a long
builder.appendOpcode(Opcodes.BSRSHIFT(a.register(), a.register(), b.register()));
operands.push(LONG);

return ip + 1;
}

private int urshift(Executable.Builder builder, Operands operands, int ip){
var b = operands.pop();
var a = operands.pop();

// Disregard operand types - treat everything as a long
builder.appendOpcode(Opcodes.BURSHIFT(a.register(), a.register(), b.register()));
operands.push(LONG);

return ip + 1;
}

private int _return(Executable.Builder builder, Operands operands, int ip){
var op = operands.pop();
builder.appendOpcode(Opcodes.RETURN(op.register()));
Expand Down

0 comments on commit cb6265d

Please sign in to comment.