Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add better IR casting #120

Merged
merged 9 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
- master
- feature/*

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-commit-check
cancel-in-progress: true

jobs:
build:
timeout-minutes: 15
Expand All @@ -17,20 +21,18 @@ jobs:
- uses: actions/setup-node@v2
with:
node-version: '20.x'
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile --prefer-offline --production=false

- uses: actions/cache@v2
id: yarn-cache
- name: Turbo Cache
uses: actions/cache@v3
with:
path: |
**/node_modules
**/.eslintcache
${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
path: .turbo
key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-yarn-

- name: Install modules
run: yarn install --frozen-lockfile
turbo-${{ github.job }}-${{ github.ref_name }}

- name: Build
run: yarn build
Expand Down
161 changes: 160 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ npx ts-c ./main.c -ps
### What works? 🔥

- [x] Local / Global variables
- [x] `float` / `double` operations using X87 stack-based registers
- [x] Advanced types `struct`, `union`, `enum`
- [x] Loops and if conditions `while`, `if`, `do while`, `for`, `break`, `continue`
- [x] Basic preprocessor with `#ifdef`, `#define`, `#include`
Expand All @@ -89,7 +90,6 @@ npx ts-c ./main.c -ps

### What does not work? 🚧

- [ ] `float` / `double` types
- [ ] Bitfields
- [ ] `goto`

Expand Down Expand Up @@ -179,6 +179,165 @@ def main(): [ret: int2B]

</details>

### Floating point operations

```c
float calculate_pi(int nbofterms) {
float x = 0.0;

for (int n = 0; n < nbofterms; n++) {
float z = 1.0 / (2 * n + 1);

if (n % 2 == 1) {
z *= -1;
}

x = (x + z);
}

return 4 * x;
}

int main() {
float pi = calculate_pi(500);
int trunc_pi = pi;
asm("xchg bx, bx");
return 0;
}
```

<details>
<summary><strong>IR Output</strong></summary>

```ruby
# --- Block calculate_pi ---
def calculate_pi(nbofterms{0}: int*2B): [ret: float4B]
x{0}: float*2B = alloca float4B
*(x{0}: float*2B) = store %0: float4B
n{0}: int*2B = alloca int2B
*(n{0}: int*2B) = store %0: int2B
L1:
%t{0}: int2B = load n{0}: int*2B
%t{1}: int2B = load nbofterms{0}: int*2B
%t{2}: i1:zf = icmp %t{0}: int2B less_than %t{1}: int2B
br %t{2}: i1:zf, true: L2, false: L3
L2:
z{0}: float*2B = alloca float4B
%t{5}: int2B = load n{0}: int*2B
%t{6}: int2B = %t{5}: int2B mul %2: char1B
%t{7}: int2B = %t{6}: int2B plus %1: char1B
%t{8}: float4B = cast %t{7}: int2B
%t{9}: float4B = %1: float4B div %t{8}: float4B
*(z{0}: float*2B) = store %t{9}: float4B
%t{11}: int2B = %t{5}: int2B mod %2: char1B
%t{12}: i1:zf = icmp %t{11}: int2B equal %1: char1B
br %t{12}: i1:zf, false: L4
L5:
%t{14}: float4B = load z{0}: float*2B
%t{15}: float4B = %t{14}: float4B mul %-1: char1B
*(z{0}: float*2B) = store %t{15}: float4B
L4:
%t{16}: float4B = load x{0}: float*2B
%t{17}: float4B = load z{0}: float*2B
%t{18}: float4B = %t{16}: float4B plus %t{17}: float4B
*(x{0}: float*2B) = store %t{18}: float4B
%t{3}: int2B = load n{0}: int*2B
%t{4}: int2B = %t{3}: int2B plus %1: int2B
*(n{0}: int*2B) = store %t{4}: int2B
jmp L1
L3:
%t{19}: float4B = load x{0}: float*2B
%t{20}: float4B = %t{19}: float4B mul %4: char1B
ret %t{20}: float4B
end-def


# --- Block main ---
def main(): [ret: int2B]
pi{0}: float*2B = alloca float4B
%t{22}: float4B = call label-offset calculate_pi :: (%500: int2B)
*(pi{0}: float*2B) = store %t{22}: float4B
trunc_pi{0}: int*2B = alloca int2B
%t{23}: float4B = load pi{0}: float*2B
%t{24}: int2B = cast %t{23}: float4B
*(trunc_pi{0}: int*2B) = store %t{24}: int2B
asm "xchg bx, bx"
ret %0: char1B
end-def

```

</details>

<details open>
<summary><strong>Binary output</strong></summary>

```asm
0x000000 <──────╮ 55 push bp
0x000001 │ 89 e5 mov bp, sp
0x000003 │ 83 ec 0c sub sp, 0xc
0x000006 │ d9 06 9b 00 fld dword [@@_$lc_0]
0x00000a │ d9 5e fc fstp dword [bp-4]
0x00000d │ c7 46 fa 00 00 mov word [bp-6], 0x0
0x000012 <────╮ │ 8b 46 04 mov ax, word [bp+4]
0x000015 │ │ 39 46 fa cmp word [bp-6], ax
0x000018 ─╮ │ │ 7c 02 jl 0x1c
0x00001a ─┼─╮ │ │ 7d 4b jge 0x67
0x00001c <╯ │ │ │ 8b 46 fa mov ax, word [bp-6]
0x00001f │ │ │ 89 c3 mov bx, ax
0x000021 │ │ │ d1 e0 shl ax, 0x1
0x000023 │ │ │ 05 01 00 add ax, 0x1
0x000026 │ │ │ 89 46 f4 mov word [bp-12], ax
0x000029 │ │ │ df 46 f4 fild word [bp-12]
0x00002c │ │ │ d9 e8 fld1
0x00002e │ │ │ d8 f1 fdiv st0, st1
0x000030 │ │ │ dd c1 ffree st1
0x000032 │ │ │ d9 5e f6 fstp dword [bp-10]
0x000035 │ │ │ 89 d8 mov ax, bx
0x000037 │ │ │ bb 02 00 mov bx, 0x2
0x00003a │ │ │ 66 99 cdq
0x00003c │ │ │ f7 fb idiv bx
0x00003e │ │ │ 83 fa 01 cmp dx, 0x1
0x000041 ─╮ │ │ │ 75 0a jnz 0x4d
0x000043 │ │ │ │ d9 46 f6 fld dword [bp-10]
0x000046 │ │ │ │ d8 0e 9f 00 fmul dword [@@_$lc_1]
0x00004a │ │ │ │ d9 5e f6 fstp dword [bp-10]
0x00004d <╯ │ │ │ d9 46 fc fld dword [bp-4]
0x000050 │ │ │ d9 46 f6 fld dword [bp-10]
0x000053 │ │ │ d9 c9 fxch st1
0x000055 │ │ │ d8 c1 fadd st0, st1
0x000057 │ │ │ dd c1 ffree st1
0x000059 │ │ │ d9 5e fc fstp dword [bp-4]
0x00005c │ │ │ 8b 46 fa mov ax, word [bp-6]
0x00005f │ │ │ 05 01 00 add ax, 0x1
0x000062 │ │ │ 89 46 fa mov word [bp-6], ax
0x000065 ───┼─╯ │ eb ab jmp 0x12
0x000067 <──╯ │ d9 46 fc fld dword [bp-4]
0x00006a │ d8 0e a3 00 fmul dword [@@_$lc_2]
0x00006e │ 89 ec mov sp, bp
0x000070 │ 5d pop bp
0x000071 │ c2 02 00 ret 0x2
0x000074 │ 55 push bp
0x000075 │ 89 e5 mov bp, sp
0x000077 │ 83 ec 0c sub sp, 0xc
0x00007a │ 68 f4 01 push 0x1f4
0x00007d ───────╯ e8 80 ff call 0x0
0x000080 d9 56 f8 fst dword [bp-8]
0x000083 d9 5e fc fstp dword [bp-4]
0x000086 d9 46 fc fld dword [bp-4]
0x000089 df 5e f4 fistp word [bp-12]
0x00008c 8b 46 f4 mov ax, word [bp-12]
0x00008f 89 46 f6 mov word [bp-10], ax
0x000092 87 db xchg bx, bx
0x000094 b8 00 00 mov ax, 0x0
0x000097 89 ec mov sp, bp
0x000099 5d pop bp
0x00009a c3 ret
0x00009b 00 00 00 00 dd 0.0
0x00009f 00 00 80 bf dd -1.0
0x0000a3 00 00 80 40 dd 4.0
```

### Simple VA lists with primitive types

```c
Expand Down
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
Loading
Loading