Skip to content

Commit

Permalink
feat: add cast to IR
Browse files Browse the repository at this point in the history
  • Loading branch information
Mati365 committed Jan 19, 2024
1 parent a1a831c commit 9b2e0dd
Show file tree
Hide file tree
Showing 40 changed files with 1,269 additions and 1,147 deletions.
2 changes: 1 addition & 1 deletion apps/x86-16-vm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"devDependencies": {
"@ts-c-compiler/compiler": "*",
"express": "^4.18.2",
"styled-components": "^6.1.1"
"styled-components": "^6.1.8"
},
"bin": {
"run-x86_16-vm": "dist/bin/server.js"
Expand Down
42 changes: 10 additions & 32 deletions assets/kernels/asm/bootsec.asm
Original file line number Diff line number Diff line change
Expand Up @@ -14,53 +14,31 @@ cpu 386
; BOOOTSEC

cpu 386
; def sum(a{0}: float*2B, b{0}: float*2B): [ret: float4B]
; def sum(a{0}: int*2B, b{0}: char*2B): [ret: int2B]
@@_fn_sum:
push bp
mov bp, sp
fld dword [bp + 4]
fld dword [bp + 8]
fxch st1
fadd st0, st1
ffree st1
movzx ax, byte [bp + 6]
xchg bx, bx
mov bx, [bp + 4]
add bx, ax ; %t{3}: int2B = %t{0}: int2B plus %t{2}: int2B
mov ax, bx
mov sp, bp
pop bp
ret 4
; def main():
@@_fn_main:
push bp
mov bp, sp
sub sp, 12
fld dword [@@_$LC_0]
sub sp, 4
mov bx, sp
fstp dword [bx]
ffree st7
fld1
sub sp, 4
mov bx, sp
fstp dword [bx]
ffree st7
call @@_fn_sum
fst dword [bp - 8]
sub sp, 4
mov bx, sp
fstp dword [bx]
ffree st7
fld1
sub sp, 4
mov bx, sp
fstp dword [bx]
ffree st7
sub sp, 2
push 97
push 3
call @@_fn_sum
fst dword [bp - 12]
fstp dword [bp - 4]
ffree st7
mov word [bp - 2], ax ; *(k{0}: int*2B) = store %t{5}: int2B
xchg bx, bx
mov sp, bp
pop bp
ret
@@_$LC_0: dd 2.0



Expand Down
57 changes: 28 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,68 +20,67 @@
"packages/*"
],
"devDependencies": {
"@changesets/cli": "^2.26.2",
"@changesets/cli": "^2.27.1",
"@commander-js/extra-typings": "^11.1.0",
"@commitlint/cli": "^17.4.0",
"@commitlint/config-conventional": "^17.4.0",
"@commitlint/types": "^17.4.0",
"@commitlint/cli": "^18.4.4",
"@commitlint/config-conventional": "^18.4.4",
"@commitlint/types": "^18.4.4",
"@rollup/plugin-node-resolve": "^15.2.3",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/jest-dom": "^6.2.0",
"@testing-library/react": "^14.1.2",
"@types/classnames": "^2.2.3",
"@types/jest": "^29.2.5",
"@types/jest": "^29.5.11",
"@types/long": "^5.0.0",
"@types/multer": "^1.4.3",
"@types/node": "^18.11.18",
"@types/multer": "^1.4.11",
"@types/node": "^20.11.5",
"@types/ramda": "^0.28.20",
"@types/styled-components": "^5.1.26",
"@typescript-eslint/eslint-plugin": "^5.48.0",
"@typescript-eslint/parser": "^5.48.0",
"@types/styled-components": "^5.1.34",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"arraybuffer-loader": "^1.0.8",
"bcrypt": "^5.1.0",
"buffer": "^6.0.3",
"chalk": "4.1.2",
"chalk": "5.3.0",
"circular-dependency-plugin": "^5.2.2",
"classnames": "^2.3.2",
"classnames": "^2.5.1",
"codemirror": "^6.0.1",
"commander": "^11.1.0",
"eslint": "^8.31.0",
"eslint": "^8.56.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-xss": "^0.1.12",
"eslint-webpack-plugin": "^3.2.0",
"eslint-webpack-plugin": "^4.0.1",
"file-loader": "^6.2.0",
"fp-ts": "^2.16.1",
"fp-ts": "^2.16.2",
"husky": "^8.0.3",
"jest": "^29.7.0",
"lint-staged": "^13.1.0",
"lint-staged": "^15.2.0",
"long": "^5.2.1",
"nodemon-webpack-plugin": "^4.8.1",
"prettier": "^2.8.2",
"pretty-quick": "^3.1.3",
"prettier": "^3.2.4",
"pretty-quick": "^4.0.0",
"prop-types": "^15.8.1",
"ramda": "^0.28.0",
"raw-loader": "^4.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"reflect-metadata": "^0.1.13",
"rollup": "^4.0.2",
"reflect-metadata": "^0.2.1",
"rollup": "^4.9.5",
"rollup-plugin-typescript2": "^0.36.0",
"rxjs": "^7.8.0",
"source-map-loader": "^4.0.1",
"source-map-loader": "^5.0.0",
"source-map-support": "^0.5.21",
"strip-ansi": "^7.0.1",
"styled-components": "^5.3.6",
"ts-enum-util": "^4.0.2",
"ts-jest": "^29.0.3",
"ts-loader": "^9.4.2",
"ts-loader": "^9.5.1",
"tslib": "^2.5.2",
"turbo": "^1.10.16",
"typescript": "^5.2.2",
"turbo": "^1.11.3",
"typescript": "^5.3.3",
"webpack": "^5.76.0",
"webpack-cli": "^5.0.1",
"webpack-manifest-plugin": "^5.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-core/src/monads/Identity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class Identity<T> implements IsEqual<Identity<T>> {
this.value = Object.freeze(value);
}

isEqual(value: Identity<T>): boolean {
isEqual(value: any): boolean {
if (!value) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-core/src/utils/mutableOmitChildKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as R from 'ramda';
* Remove child keys from parent keeping parent reference
*/
export function mutableOmitChildKeys(parent: object, child: object): object {
R.forEach(key => {
R.forEach((key: any) => {
delete parent[key];
}, R.keys(child));

Expand Down
21 changes: 17 additions & 4 deletions packages/compiler-grammar/src/tree/TreeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class TreeNode<K = string, C extends TreeNode<K, C> = any>
const { children } = this;

if (children) {
R.forEach(child => {
R.forEach((child: any) => {
visitor.visit(child);
}, children);
}
Expand All @@ -64,7 +64,11 @@ export class TreeNode<K = string, C extends TreeNode<K, C> = any>
* Node withs ingle value
*/
export class ValueNode<T, K = string> extends TreeNode<K> {
constructor(kind: K, loc: NodeLocation, readonly value: T) {
constructor(
kind: K,
loc: NodeLocation,
readonly value: T,
) {
super(kind, loc, null);
}

Expand All @@ -85,7 +89,11 @@ export class BinaryNode<
K = string,
T extends TreeNode<K> = TreeNode<K>,
> extends TreeNode<K> {
constructor(kind: K, public left: T, public right: T) {
constructor(
kind: K,
public left: T,
public right: T,
) {
super(kind, left?.loc);
}

Expand Down Expand Up @@ -144,7 +152,12 @@ export class BinaryOpNode<
K = string,
T extends TreeNode<K> = TreeNode<K>,
> extends BinaryNode<K, T> {
constructor(kind: K, public op: TokenType, left: T, right: T) {
constructor(
kind: K,
public op: TokenType,
left: T,
right: T,
) {
super(kind, left, right);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export class X86StdcallFnCaller implements X86ConventionalFnCaller {
});

const stackRegResult = x87regs.tryResolveIRArgAsReg({
allowCast: true,
stackTop: true,
castedType: declBaseType,
arg,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export function compileCallInstruction(attrs: CallInstructionCompilerAttrs) {
const stackVar = stackFrame.allocSpillVariable(
outputVar.type.getByteSize(),
);

const memAddr = stackFrame.getLocalVarStackRelAddress(stackVar.name, {
withSize: true,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { IRCastInstruction } from 'frontend/ir/instructions';
import { CBackendError, CBackendErrorCode } from 'backend/errors/CBackendError';

import { genInstruction } from 'arch/x86/asm-utils';
import { isPrimitiveLikeType } from 'frontend/analyze';

import { X86CompilerInstructionFnAttrs } from '../../constants/types';
import { X86CompileInstructionOutput } from './shared';

type CastInstructionCompilerAttrs =
X86CompilerInstructionFnAttrs<IRCastInstruction>;

export function compileCastInstruction({
instruction,
context,
}: CastInstructionCompilerAttrs) {
const { allocator } = context;
const { inputVar, outputVar } = instruction;
const { regs, x87regs, stackFrame, lifetime } = allocator;

const output = new X86CompileInstructionOutput();

if (
!isPrimitiveLikeType(inputVar.type) ||
!isPrimitiveLikeType(outputVar.type)
) {
throw new CBackendError(CBackendErrorCode.CANNOT_CAST_VARIABLES);
}

if (inputVar.type.isIntegral() && outputVar.type.isFloating()) {
// int -> float
const pushResult = x87regs.tryResolveIRArgAsReg({
arg: inputVar,
castedType: outputVar.type,
allowCast: true,
});

output.appendGroup(pushResult.asm);
x87regs.tracker.setOwnership({
...pushResult.entry,
varName: outputVar.name,
});
} else if (inputVar.type.isFloating() && outputVar.type.isIntegral()) {
// int -> float
const spillVar = stackFrame.allocSpillVariable(
outputVar.type.getByteSize(),
);

const spillMemAddr = stackFrame.getLocalVarStackRelAddress(spillVar.name, {
withSize: true,
});

const pushResult = x87regs.tryResolveIRArgAsReg({
arg: inputVar,
stackTop: true,
});

const reg = regs.requestReg({
size: outputVar.type.getByteSize(),
});

output.appendGroup(
x87regs.storeStackRegAtAddress({
reg: pushResult.entry.reg,
address: spillMemAddr,
integral: true,
pop: !lifetime.isVariableLaterUsed(
allocator.iterator.offset,
spillVar.name,
),
}).asm,
);

output.appendInstructions(
...reg.asm,
genInstruction('mov', reg.value, spillMemAddr),
);

output.appendGroup(pushResult.asm);
regs.ownership.setOwnership(outputVar.name, {
reg: reg.value,
});
} else if (outputVar.type.getByteSize() - inputVar.type.getByteSize() === 1) {
const extendedReg = regs.requestReg({
size: outputVar.type.getByteSize(),
});

const rValue = regs.tryResolveIrArg({
arg: inputVar,
});

output.appendInstructions(
...extendedReg.asm,
...rValue.asm,
genInstruction('movzx', extendedReg.value, rValue.value),
);

regs.ownership.setOwnership(outputVar.name, {
reg: extendedReg.value,
});
} else {
regs.ownership.aliasOwnership(inputVar.name, outputVar.name);
}

return output;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { compilePhiInstruction } from './compilePhiInstruction';
import { compileRetInstruction } from './compileRetInstruction';
import { compileLabelOffsetInstruction } from './compileLabelOffsetInstruction';
import { compileCallInstruction } from './compileCallInstruction';
import { compileCastInstruction } from './compileCastInstruction';
import { compileAsmInstruction } from './asm';
import {
compileIntMathSingleInstruction,
Expand Down Expand Up @@ -116,6 +117,10 @@ export function compileFnDeclInstructionsBlock({
fnOutput.appendGroup(compileICmpInstruction(arg));
break;

case IROpcode.CAST:
fnOutput.appendGroup(compileCastInstruction(arg));
break;

case IROpcode.COMMENT:
fnOutput.asm.push(
genComment((<IRCommentInstruction>instruction).comment),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export function compileStoreInstruction({
const pushResult = x87regs.tryResolveIRArgAsReg({
arg: value,
castedType: baseOutputType,
allowCast: true,
});

output.appendGroup(pushResult.asm);
Expand Down Expand Up @@ -166,7 +167,7 @@ export function compileStoreInstruction({

output.appendGroups(storeResult.asm);
} else {
output.appendInstructions('; MISSING SHIT');
throw new Error('TODO');
}
} else {
// store int in integer variable
Expand Down
Loading

0 comments on commit 9b2e0dd

Please sign in to comment.