... | ... | @@ -81,4 +81,74 @@ Examples: |
|
|
* `{float, float, double}` -> `({float, float, double}*)`
|
|
|
* `{float, float}` -> `(i64)`
|
|
|
* `{double}` -> `(i64)`
|
|
|
* `{double, double}` -> `({double, double}*)` |
|
|
\ No newline at end of file |
|
|
* `{double, double}` -> `({double, double}*)`
|
|
|
|
|
|
Note: the above can be verified on Appveyor by:
|
|
|
```yaml
|
|
|
image: Visual Studio 2017
|
|
|
# List of preinstalled software in the image:
|
|
|
# https://www.appveyor.com/docs/windows-images-software/
|
|
|
|
|
|
build_script:
|
|
|
- call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd" -arch=x64
|
|
|
- cl /W3 /GR /EHsc /MD /O2 /Ob2 /MP /bigobj /wd4251 /wd4996 /GR- /FS /FAs conv.c
|
|
|
- type conv.asm
|
|
|
- conv
|
|
|
```
|
|
|
and `conv.c`:
|
|
|
```c
|
|
|
#include <stdio.h>
|
|
|
|
|
|
struct _lfortran_single_complex {
|
|
|
float re, im;
|
|
|
};
|
|
|
|
|
|
struct _lfortran_double_complex {
|
|
|
double re, im;
|
|
|
};
|
|
|
|
|
|
typedef struct _lfortran_single_complex float_complex_t;
|
|
|
typedef struct _lfortran_double_complex double_complex_t;
|
|
|
|
|
|
|
|
|
void cf(float_complex_t x)
|
|
|
{
|
|
|
printf("f32: %.15f %.15f\n", x.re, x.im);
|
|
|
}
|
|
|
|
|
|
void zf(double_complex_t x)
|
|
|
{
|
|
|
printf("f64: %.15f %.15f\n", x.re, x.im);
|
|
|
}
|
|
|
|
|
|
int main() {
|
|
|
float_complex_t f;
|
|
|
double_complex_t d;
|
|
|
f.re = 3.5;
|
|
|
f.im = 4.5;
|
|
|
cf(f);
|
|
|
|
|
|
d.re = 3.5;
|
|
|
d.im = 4.5;
|
|
|
zf(d);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
```
|
|
|
It generates:
|
|
|
```asm
|
|
|
zf PROC ; COMDAT
|
|
|
; 22 : printf("f64: %.15f %.15f\n", x.re, x.im);
|
|
|
movsd xmm2, QWORD PTR [rcx+8]
|
|
|
movsd xmm1, QWORD PTR [rcx]
|
|
|
|
|
|
|
|
|
cf PROC ; COMDAT
|
|
|
; 16 : {
|
|
|
mov QWORD PTR x$[rsp], rcx
|
|
|
; 17 : printf("f32: %.15f %.15f\n", x.re, x.im);
|
|
|
lea rcx, OFFSET FLAT:??_C@_0BC@KIANHDOD@f32?3?5?$CF?415f?5?$CF?415f?6@
|
|
|
movss xmm2, DWORD PTR x$[rsp+4]
|
|
|
movss xmm1, DWORD PTR x$[rsp]
|
|
|
```
|
|
|
So in the `zf` (`double complex`) case, it reads the two doubles from `[rcx]` and `[rcx+8]`. So the `f({double, double}*)` calling convention. In the `cf` (`float complex`) case, it puts `rcx` to `[rsp]` and then reads the two numbers as `[rsp]` and `[rsp+4]`, so `rcx` contained both floats as a single `i64`. So the ``f(i64)` calling convention. |
|
|
\ No newline at end of file |