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

Generate position independent code #50

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
8 changes: 4 additions & 4 deletions src/Tinyrossa-POWER/TRPPC64Linux.class.st
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Class {
#name : #TRPPC64Linux,
#superclass : #TRCompilationTarget,
#category : #'Tinyrossa-POWER-Compile'
#superclass : #TRTarget,
#category : #'Tinyrossa-POWER-Target'
}

{ #category : #accessing }
{ #category : #'accessing - config - compilation' }
TRPPC64Linux >> codeGeneratorClass [
^ TRPPC64CodeGenerator
]
Expand All @@ -14,7 +14,7 @@ TRPPC64Linux >> name [
^ 'powerpc64le-linux'
]

{ #category : #accessing }
{ #category : #'accessing - config - compilation' }
TRPPC64Linux >> systemLinkageClass [
^ TRPPC64PSABILinkage
]
6 changes: 6 additions & 0 deletions src/Tinyrossa-POWER/TRRuntimeConfig.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Extension { #name : #TRRuntimeConfig }

{ #category : #'*Tinyrossa-POWER' }
TRRuntimeConfig class >> forPPC64Linux [
^ self forTarget: TRPPC64Linux default
]
8 changes: 4 additions & 4 deletions src/Tinyrossa-RISCV/TRRV64GLinux.class.st
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Class {
#name : #TRRV64GLinux,
#superclass : #TRCompilationTarget,
#category : #'Tinyrossa-RISCV-Compile'
#superclass : #TRTarget,
#category : #'Tinyrossa-RISCV-Target'
}

{ #category : #accessing }
{ #category : #'accessing - config - compilation' }
TRRV64GLinux >> codeGeneratorClass [
^ TRRV64GCodeGenerator
]
Expand All @@ -14,7 +14,7 @@ TRRV64GLinux >> name [
^ 'riscv64-linux'
]

{ #category : #accessing }
{ #category : #'accessing - config - compilation' }
TRRV64GLinux >> systemLinkageClass [
^ TRRV64GPSABILinkage
]
48 changes: 19 additions & 29 deletions src/Tinyrossa-RISCV/TRRV64GPSABILinkage.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -98,39 +98,29 @@ TRRV64GPSABILinkage >> generateCall: node [

addrReg := codegen evaluator evaluate: node child1.
call := generate jalr: ra, addrReg, 0.
call dependencies: deps.
] ifFalse: [
"If the call a recursive call..."
node symbol == codegen compilation functionSymbol ifTrue: [
"...then generate 'jal ra, <function>'..."
call := generate jal: ra, node symbol.
node symbol = codegen compilation functionSymbol ifTrue: [
"...then use simple `jal`, hoping offset would fit into 20 bits..."
call := generate jal: ra, node symbol .
call dependencies: deps.
] ifFalse: [
"...otherwise..."
codegen compilation isAOT ifTrue: [
"
In AOT mode we generate call and let the (runtime) linker
to properly relocate it.
"
call := generate call: node symbol
] ifFalse: [
"
In JIT mode we load address directly into 'ra'
(as opposite to allocating new v-register as in indirect case
above) because will be clobbered anyways by jalr storing return
address. This lowers the pressure on RA.

Also note that rather than this, we should generate a trampoline
and call calle through it. Or relative jal if it's close enough.
That's left as future work.
"
self assert: node symbol address notNil description: 'No address set for function symbol'.

codegen loadConstant64: node symbol address into: ra.
call := generate jalr: ra, ra, 0.
].
"...otherwise use auipc + jalr pair with relocations.

We load address directly into 'ra' (as opposite to allocating
new v-register as in indirect case above) because will be clobbered
anyways by jalr storing return address. This lowers the pressure on RA."

| auipc |

auipc := generate auipc: ra, (R_RISCV_CALL_PLT % node symbol).
auipc dependencies: (TRRegisterDependencies pre: deps pre).

call := generate jalr: ra, ra, 0.
call dependencies: (TRRegisterDependencies post: deps post)
].
].
call dependencies: deps.


"Note that link register has been overwritten"
codegen linkRegisterKilled: true.
Expand All @@ -140,7 +130,7 @@ TRRV64GPSABILinkage >> generateCall: node [
retVreg := nil.
] ifFalse:[
retVreg := codegen allocateRegister.
deps post addDependency: retVreg on: a0.
call dependencies post addDependency: retVreg on: a0.
].

^ retVreg
Expand Down
6 changes: 6 additions & 0 deletions src/Tinyrossa-RISCV/TRRuntimeConfig.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Extension { #name : #TRRuntimeConfig }

{ #category : #'*Tinyrossa-RISCV' }
TRRuntimeConfig class >> forRV64GLinux [
^ self forTarget: TRRV64GLinux default
]
72 changes: 60 additions & 12 deletions src/Tinyrossa-Tests/TRCompilationTestCase.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ TRCompilationTestCase >> setUp [

compilation := TRCompilation forTarget: target.
compilation config stressRA: (testParameters at: #stressRA).
shell := TRCompilationTestShell forCompilation: compilation.

shell := TRCompilationTestShell forTarget: target.
]

{ #category : #accessing }
Expand Down Expand Up @@ -200,7 +201,7 @@ TRCompilationTestCase >> test01_bytecode_abs [

compilation compile.

self assert: (shell call: 2) equals: 2 abs.
self assert: (shell inject: compilation andInvokeWith: { 2 }) equals: 2 abs.
]

{ #category : #tests }
Expand All @@ -218,7 +219,7 @@ TRCompilationTestCase >> test02_iconst [
compilation optimize.
compilation compile.

self assert: (shell call) equals: x.
self assert: (shell inject: compilation andInvokeWith: #()) equals: x.

"
TRRV64GCompilationTests debug: #test02_iconst_p
Expand All @@ -244,21 +245,68 @@ TRCompilationTestCase >> test03_lconst [
compilation optimize.
compilation compile.

self assert: (shell call) equals: x.
self assert: (shell inject: compilation andInvokeWith: #()) equals: x.

"
TRRV64GCompilationTests debug: #test03_lconst_n
TRPPC64CompilationTests debug: #test03_lconst_n
"
]

{ #category : #tests }
TRCompilationTestCase >> test04_call_resolved [
| comp1 bldr1 comp2 bldr2 |

self target name = 'powerpc64le-linux' ifTrue: [
self skip: 'Skipped since calls are not implemented for POWER (see issue #45)'.
].

" ### CALLEE ### "
comp1 := TRCompilation forConfig: compilation config.
bldr1 := comp1 builder.
bldr1 defineName: 'callee' type: Int32.
bldr1 defineParameter: 'x' type: Int32.
bldr1 ireturn:
{ bldr1 iadd:
{ bldr1 iload: 'x'.
bldr1 iconst: 1 } }.
comp1 optimize.
comp1 compile.

" ### CALLER ### "
comp2 := TRCompilation forConfig: compilation config.
bldr2 := comp2 builder.
bldr2 defineName: 'caller' type: Int32.
bldr2 defineParameter: 'x' type: Int32.
bldr2 defineFunction: 'callee' type: Int32.
bldr2 ireturn:
{ bldr2 iadd:
{ bldr2 iload: 'x'.
bldr2 icall: { bldr2 iload: 'x' . 'callee' } } }.
comp2 optimize.
comp2 compile.

" ### ######### ### "

shell inject: comp1.
shell inject: comp2.

self assert: (shell invoke: comp2 functionSymbol with: { 10 } types: { Int32 })
equals: 21

"
TRRV64GCompilationTests debug: #test03_lconst_n
TRPPC64CompilationTests debug: #test03_lconst_n
"
]

{ #category : #'tests - examples' }
TRCompilationTestCase >> test_example01_meaningOfLife [
TRCompilationExamples new
compilation: compilation;
example01_meaningOfLife.

self assert: (shell call) equals: 42.
self assert: (shell inject: compilation andInvokeWith: #()) equals: 42.
]

{ #category : #'tests - examples' }
Expand All @@ -267,7 +315,7 @@ TRCompilationTestCase >> test_example03_signum [
compilation: compilation;
example03_signum.

self assert: (shell call:-5) equals: -5 sign.
self assert: (shell inject: compilation andInvokeWith: { -5 }) equals: -5 sign.
]

{ #category : #'tests - examples' }
Expand All @@ -276,7 +324,7 @@ TRCompilationTestCase >> test_example04_factorial_i [
compilation: compilation;
example04_factorial_i.

self assert: (shell call:5) equals: 5 factorial.
self assert: (shell inject: compilation andInvokeWith: { 5 }) equals: 5 factorial.
]

{ #category : #'tests - examples' }
Expand All @@ -288,15 +336,15 @@ TRCompilationTestCase >> test_example05_factorial_r [
compilation: compilation;
example05_factorial_r.

self assert: (shell call:5) equals: 5 factorial.
self assert: (shell inject: compilation andInvokeWith: { 5 }) equals: 5 factorial.
]

{ #category : #'tests - examples' }
TRCompilationTestCase >> test_example08_bytecode_compiler [
TRCompilationExamples new
compilation: compilation;
example08_bytecode_compiler.
self assert: (shell call:2) equals: 2 factorial.
self assert: (shell inject: compilation andInvokeWith: { 2 }) equals: 2 factorial.
]

{ #category : #'tests - examples' }
Expand All @@ -309,7 +357,7 @@ TRCompilationTestCase >> test_example09_signum_2 [
compilation: compilation;
example09_signum_2.

self assert: (shell call:-1) equals: -1 sign.
self assert: (shell inject: compilation andInvokeWith: { -1 }) equals: -1 sign.
]

{ #category : #'tests - examples' }
Expand All @@ -321,7 +369,7 @@ TRCompilationTestCase >> test_example15_add_with_overflow_check [
TRCompilationExamples new
compilation: compilation;
example15_add_with_overflow_check.
self assert: (shell call: 16r7FFFFFFE _: 2 ) equals: 0.
self assert: (shell inject: compilation andInvokeWith: { 16r7FFFFFFE . 2 }) equals: 0.
]

{ #category : #'tests - examples' }
Expand All @@ -333,7 +381,7 @@ TRCompilationTestCase >> test_example16_factorial_i_with_overflow [
TRCompilationExamples new
compilation: compilation;
example16_factorial_i_with_overflow.
self assert: (shell call:13)equals: -1.
self assert: (shell inject: compilation andInvokeWith: { 13 })equals: -1.


"
Expand Down
Loading
Loading