rbdc 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/dyncall/CMakeLists.txt +3 -3
  3. data/dyncall/ChangeLog +33 -0
  4. data/dyncall/ChangeLog.orig +274 -0
  5. data/dyncall/LICENSE +1 -1
  6. data/dyncall/README +3 -5
  7. data/dyncall/ToDo +27 -18
  8. data/dyncall/ToDo.orig +201 -0
  9. data/dyncall/autovar/autovar_ARCH.h +1 -1
  10. data/dyncall/buildsys/vs2005/vs2005.sln +0 -9
  11. data/dyncall/cconv.lang +36 -0
  12. data/dyncall/configure +17 -9
  13. data/dyncall/configure.bat +1 -1
  14. data/dyncall/dyncall/dyncall.h +2 -1
  15. data/dyncall/dyncall/dyncall_call.S +9 -1
  16. data/dyncall/dyncall/dyncall_call_mips_n32.S +192 -0
  17. data/dyncall/dyncall/dyncall_call_mips_n64.S +197 -0
  18. data/dyncall/dyncall/dyncall_call_mips_n64.h +2 -0
  19. data/dyncall/dyncall/{dyncall_call_mips_o32_gas.s → dyncall_call_mips_o32.S} +44 -42
  20. data/dyncall/dyncall/dyncall_call_mips_o32.h +8 -3
  21. data/dyncall/dyncall/dyncall_call_ppc32.S +3 -1
  22. data/dyncall/dyncall/dyncall_call_ppc32.h +4 -3
  23. data/dyncall/dyncall/dyncall_call_ppc64.S +1 -1
  24. data/dyncall/dyncall/dyncall_call_ppc64.h +3 -0
  25. data/dyncall/dyncall/dyncall_call_x64.S +27 -2
  26. data/dyncall/dyncall/dyncall_call_x64.h +2 -1
  27. data/dyncall/dyncall/dyncall_call_x64_generic_masm.asm +13 -2
  28. data/dyncall/dyncall/dyncall_call_x86.S +6 -6
  29. data/dyncall/dyncall/dyncall_call_x86.h +7 -7
  30. data/dyncall/dyncall/dyncall_call_x86_generic_masm.asm +6 -7
  31. data/dyncall/dyncall/dyncall_callvm_mips_n64.c +27 -9
  32. data/dyncall/dyncall/dyncall_callvm_mips_o32.c +38 -31
  33. data/dyncall/dyncall/dyncall_callvm_mips_o32.c.orig +247 -0
  34. data/dyncall/dyncall/dyncall_callvm_x64.c +57 -3
  35. data/dyncall/dyncall/dyncall_callvm_x86.c +32 -32
  36. data/dyncall/dyncall/dyncall_macros.h +11 -8
  37. data/dyncall/dyncall/dyncall_struct.c +12 -6
  38. data/dyncall/dyncall/dyncall_struct.h +1 -1
  39. data/dyncall/dyncall/dyncall_vector.c +13 -12
  40. data/dyncall/dyncall/dyncall_vector.c.orig +53 -0
  41. data/dyncall/dyncall/gen-masm.sh +4 -5
  42. data/dyncall/dyncallback/dyncall_args_mips.h +24 -6
  43. data/dyncall/dyncallback/dyncall_args_mips64.c +3 -3
  44. data/dyncall/dyncallback/dyncall_args_mips_o32.c +19 -6
  45. data/dyncall/dyncallback/dyncall_callback_arch.S +11 -1
  46. data/dyncall/dyncallback/{dyncall_callback_mips_n32_gas.s → dyncall_callback_mips_n32.S} +1 -1
  47. data/dyncall/dyncallback/{dyncall_callback_mips_n64_gas.s → dyncall_callback_mips_n64.S} +39 -25
  48. data/dyncall/dyncallback/{dyncall_callback_mips_o32_gas.s → dyncall_callback_mips_o32.S} +29 -13
  49. data/dyncall/dyncallback/dyncall_callback_x86_masm.asm +0 -1
  50. data/dyncall/dyncallback/dyncall_thunk.h +1 -1
  51. data/dyncall/dyncallback/gen-masm.sh +3 -5
  52. data/dyncall/dynload/dynload.3 +16 -4
  53. data/dyncall/dynload/dynload_unix.c +101 -53
  54. data/dyncall/dynload/dynload_windows.c +76 -3
  55. data/dyncall/portasm/README.txt +1 -1
  56. data/dyncall/portasm/gen-masm.sh +5 -1
  57. metadata +14 -13
  58. data/dyncall/buildsys/vs2005/test_plain/test_plain.vcproj +0 -202
  59. data/dyncall/dyncall/dyncall_call_mips_gas.S +0 -37
  60. data/dyncall/dyncall/dyncall_call_mips_n32_gas.s +0 -192
  61. data/dyncall/dyncall/dyncall_call_mips_n64_gas.s +0 -192
  62. data/dyncall/dyncallback/dyncall_callback_mips_gas.S +0 -38
@@ -6,7 +6,7 @@
6
6
  Description:
7
7
  License:
8
8
 
9
- Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
9
+ Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>,
10
10
  Tassilo Philipp <tphilipp@potion-studios.com>
11
11
 
12
12
  Permission to use, copy, modify, and distribute this software for any
@@ -54,6 +54,7 @@ extern "C" {
54
54
 
55
55
  void dcCall_x64_sysv(DCsize stacksize, DCpointer stackdata, DCpointer regdata_i, DCpointer regdata_f, DCpointer target);
56
56
  void dcCall_x64_win64(DCsize stacksize, DCpointer stackdata, DCpointer regdata, DCpointer target);
57
+ void dcCall_x64_syscall_sysv(DCpointer argdata, DCpointer target);
57
58
 
58
59
  #ifdef __cplusplus
59
60
  }
@@ -1,6 +1,5 @@
1
1
  ; auto-generated by gen-masm.sh
2
2
  .CODE
3
-
4
3
  dcCall_x64_sysv PROC
5
4
  OPTION PROLOGUE:NONE, EPILOGUE:NONE
6
5
  push RBP
@@ -34,7 +33,7 @@ OPTION PROLOGUE:NONE, EPILOGUE:NONE
34
33
  pop RBX
35
34
  pop RBP
36
35
  ret
37
- dcCALl_x64_sysv ENDP
36
+ dcCall_x64_sysv ENDP
38
37
  dcCall_x64_win64 PROC
39
38
  OPTION PROLOGUE:NONE, EPILOGUE:NONE
40
39
  push RBP
@@ -67,4 +66,16 @@ OPTION PROLOGUE:NONE, EPILOGUE:NONE
67
66
  pop RBP
68
67
  ret
69
68
  dcCall_x64_win64 ENDP
69
+ dcCall_x64_syscall_sysv PROC
70
+ OPTION PROLOGUE:NONE, EPILOGUE:NONE
71
+ mov RAX,RSI
72
+ mov R9,qword ptr [RDI+40]
73
+ mov R8,qword ptr [RDI+32]
74
+ mov R10,qword ptr [RDI+24]
75
+ mov RDX,qword ptr [RDI+16]
76
+ mov RSI,qword ptr [RDI+8]
77
+ mov RDI,qword ptr [RDI+0]
78
+ SYSCALL
79
+ ret
80
+ dcCall_x64_syscall_sysv ENDP
70
81
  END
@@ -182,8 +182,8 @@ END_PROC(dcCall_x86_win32_fast)
182
182
 
183
183
  */
184
184
 
185
- GLOBAL(dcCall_x86_sys_int80h_linux)
186
- BEGIN_PROC(dcCall_x86_sys_int80h_linux)
185
+ GLOBAL(dcCall_x86_syscall_int80h_linux)
186
+ BEGIN_PROC(dcCall_x86_syscall_int80h_linux)
187
187
  PUSH(EBP) /* prolog. */
188
188
  MOVL(ESP,EBP)
189
189
  PUSH(EBX) /* save preserved. */
@@ -203,7 +203,7 @@ BEGIN_PROC(dcCall_x86_sys_int80h_linux)
203
203
  MOVL(EBP,ESP) /* epilog. */
204
204
  POP(EBP)
205
205
  RET()
206
- END_PROC(dcCall_x86_sys_int80h_linux)
206
+ END_PROC(dcCall_x86_syscall_int80h_linux)
207
207
 
208
208
  /*--- syscall int80 bsd -----------------------------------------------------
209
209
 
@@ -212,8 +212,8 @@ END_PROC(dcCall_x86_sys_int80h_linux)
212
212
 
213
213
  */
214
214
 
215
- GLOBAL(dcCall_x86_sys_int80h_bsd)
216
- BEGIN_PROC(dcCall_x86_sys_int80h_bsd)
215
+ GLOBAL(dcCall_x86_syscall_int80h_bsd)
216
+ BEGIN_PROC(dcCall_x86_syscall_int80h_bsd)
217
217
  PUSH(EBP) /* prolog. */
218
218
  MOVL(ESP,EBP)
219
219
  PUSH(ESI) /* save preserved. */
@@ -233,7 +233,7 @@ BEGIN_PROC(dcCall_x86_sys_int80h_bsd)
233
233
  _do_int:
234
234
  INT(LIT(HEX(80)))
235
235
  RET()
236
- END_PROC(dcCall_x86_sys_int80h_bsd)
236
+ END_PROC(dcCall_x86_syscall_int80h_bsd)
237
237
 
238
238
  END_ASM
239
239
 
@@ -53,14 +53,14 @@ extern "C" {
53
53
  */
54
54
 
55
55
  #if defined(DC__OS_Plan9) /* No support for other cconvs on Plan9 and vice-versa. */
56
- void dcCall_x86_plan9 (DCpointer target, DCpointer stackdata, DCsize size);
56
+ void dcCall_x86_plan9 (DCpointer target, DCpointer stackdata, DCsize size);
57
57
  #else
58
- void dcCall_x86_cdecl (DCpointer target, DCpointer stackdata, DCsize size);
59
- void dcCall_x86_win32_std (DCpointer target, DCpointer stackdata, DCsize size);
60
- void dcCall_x86_win32_fast (DCpointer target, DCpointer stackdata, DCsize size);
61
- void dcCall_x86_win32_msthis (DCpointer target, DCpointer stackdata, DCsize size);
62
- void dcCall_x86_sys_int80h_linux (DCpointer target, DCpointer stackdata, DCsize size);
63
- void dcCall_x86_sys_int80h_bsd (DCpointer target, DCpointer stackdata, DCsize size);
58
+ void dcCall_x86_cdecl (DCpointer target, DCpointer stackdata, DCsize size);
59
+ void dcCall_x86_win32_std (DCpointer target, DCpointer stackdata, DCsize size);
60
+ void dcCall_x86_win32_fast (DCpointer target, DCpointer stackdata, DCsize size);
61
+ void dcCall_x86_win32_msthis (DCpointer target, DCpointer stackdata, DCsize size);
62
+ void dcCall_x86_syscall_int80h_linux(DCpointer target, DCpointer stackdata, DCsize size);
63
+ void dcCall_x86_syscall_int80h_bsd (DCpointer target, DCpointer stackdata, DCsize size);
64
64
  #endif
65
65
 
66
66
  #ifdef __cplusplus
@@ -2,7 +2,6 @@
2
2
  .386
3
3
  .MODEL FLAT
4
4
  .CODE
5
-
6
5
  _dcCall_x86_cdecl PROC
7
6
  OPTION PROLOGUE:NONE, EPILOGUE:NONE
8
7
  push EBP
@@ -89,10 +88,10 @@ OPTION PROLOGUE:NONE, EPILOGUE:NONE
89
88
  pop EBP
90
89
  ret
91
90
  _dcCall_x86_win32_fast ENDP
92
- _dcCall_x86_sys_int80h_linux PROC
91
+ _dcCall_x86_syscall_int80h_linux PROC
93
92
  OPTION PROLOGUE:NONE, EPILOGUE:NONE
94
93
  push EBP
95
- mov EBP,ESP
94
+ mov EBP,ESP
96
95
  push EBX
97
96
  push ESI
98
97
  push EDI
@@ -110,11 +109,11 @@ OPTION PROLOGUE:NONE, EPILOGUE:NONE
110
109
  mov ESP,EBP
111
110
  pop EBP
112
111
  ret
113
- _dcCall_x86_sys_int80h_linux ENDP
114
- _dcCall_x86_sys_int80h_bsd PROC
112
+ _dcCall_x86_syscall_int80h_linux ENDP
113
+ _dcCall_x86_syscall_int80h_bsd PROC
115
114
  OPTION PROLOGUE:NONE, EPILOGUE:NONE
116
115
  push EBP
117
- mov EBP,ESP
116
+ mov EBP,ESP
118
117
  push ESI
119
118
  push EDI
120
119
  mov ESI,dword ptr [EBP+12]
@@ -132,5 +131,5 @@ OPTION PROLOGUE:NONE, EPILOGUE:NONE
132
131
  _do_int:
133
132
  int 80h
134
133
  ret
135
- _dcCall_x86_sys_int80h_bsd ENDP
134
+ _dcCall_x86_syscall_int80h_bsd ENDP
136
135
  END
@@ -58,7 +58,9 @@ static void dc_callvm_reset_mips_n64(DCCallVM* in_self)
58
58
  DCCallVM_mips_n64* self = (DCCallVM_mips_n64*)in_self;
59
59
  dcVecReset(&self->mVecHead);
60
60
  self->mRegCount = 0;
61
+ #if defined(DC__ABI_HARDFLOAT)
61
62
  self->mRegData.mUseDouble = 0LL;
63
+ #endif /* DC__ABI_HARDFLOAT */
62
64
  }
63
65
 
64
66
 
@@ -75,24 +77,24 @@ static void dc_callvm_free_mips_n64(DCCallVM* in_self)
75
77
 
76
78
  /* arg int -- fillup 64-bit integer register file OR push on stack */
77
79
 
78
- static void dc_callvm_argLongLong_mips_n64(DCCallVM* in_self, DClonglong Lv)
80
+ static void dc_callvm_argLongLong_mips_n64(DCCallVM* in_self, DClonglong x)
79
81
  {
80
82
  DCCallVM_mips_n64* self = (DCCallVM_mips_n64*)in_self;
81
83
  /* fillup integer register file */
82
84
  if (self->mRegCount < 8)
83
- self->mRegData.mIntData[self->mRegCount++] = Lv;
85
+ self->mRegData.mIntData[self->mRegCount++] = x;
84
86
  else
85
- dcVecAppend(&self->mVecHead, &Lv, sizeof(DClonglong));
87
+ dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong));
86
88
  }
87
89
 
88
- static void dc_callvm_argInt_mips_n64(DCCallVM* in_self, DCint i)
90
+ static void dc_callvm_argInt_mips_n64(DCCallVM* in_self, DCint x)
89
91
  {
90
- dc_callvm_argLongLong_mips_n64(in_self, (DClonglong) i );
92
+ dc_callvm_argLongLong_mips_n64(in_self, (DClonglong)x);
91
93
  }
92
94
 
93
95
  static void dc_callvm_argPointer_mips_n64(DCCallVM* in_self, DCpointer x)
94
96
  {
95
- dc_callvm_argLongLong_mips_n64(in_self, * (DClonglong*) &x );
97
+ dc_callvm_argLongLong_mips_n64(in_self, *(DClonglong*)&x);
96
98
  }
97
99
 
98
100
  static void dc_callvm_argBool_mips_n64(DCCallVM* in_self, DCbool x)
@@ -117,25 +119,41 @@ static void dc_callvm_argLong_mips_n64(DCCallVM* in_self, DClong x)
117
119
 
118
120
  static void dc_callvm_argDouble_mips_n64(DCCallVM* in_self, DCdouble x)
119
121
  {
122
+ #if defined(DC__ABI_HARDFLOAT)
120
123
  DCCallVM_mips_n64* self = (DCCallVM_mips_n64*)in_self;
121
124
  if (self->mRegCount < 8) {
122
125
  self->mRegData.mUseDouble |= 1<<( self->mRegCount );
123
126
  self->mRegData.mFloatData[self->mRegCount++].d = x;
124
127
  } else {
125
- dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble) );
128
+ dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
126
129
  }
130
+ #else
131
+ dc_callvm_argLongLong_mips_n64(in_self, *(DClonglong*)&x);
132
+ #endif /* DC__ABI_HARDFLOAT */
127
133
  }
128
134
 
129
135
  static void dc_callvm_argFloat_mips_n64(DCCallVM* in_self, DCfloat x)
130
136
  {
137
+ #if defined(DC__ABI_HARDFLOAT)
131
138
  DCCallVM_mips_n64* self = (DCCallVM_mips_n64*)in_self;
132
139
  if (self->mRegCount < 8) {
133
140
  /*self->mRegData.mFloatData[self->mRegCount++].d = (DCdouble) x;*/
134
141
  self->mRegData.mFloatData[self->mRegCount++].f = x;
135
142
  } else {
136
- dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat) );
137
- dcVecSkip(&self->mVecHead, sizeof(DCfloat) );
143
+ dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat));
144
+ dcVecSkip(&self->mVecHead, sizeof(DCfloat));
145
+ }
146
+ #else
147
+ DCfloat f[] = {x,0.f};
148
+ # if defined(DC__Endian_BIG)
149
+ // floats in regs always right justified
150
+ if (((DCCallVM_mips_n64*)in_self)->mRegCount < 8) {
151
+ f[1] = f[0];
152
+ f[0] = 0.f;
138
153
  }
154
+ # endif /* DC__Endian_BIG */
155
+ dc_callvm_argLongLong_mips_n64(in_self, *(DClonglong*)&f);
156
+ #endif /* DC__ABI_HARDFLOAT */
139
157
  }
140
158
 
141
159
 
@@ -77,7 +77,7 @@ static void dc_callvm_argInt_mips_o32(DCCallVM* in_self, DCint i)
77
77
 
78
78
  static void dc_callvm_argPointer_mips_o32(DCCallVM* in_self, DCpointer x)
79
79
  {
80
- dc_callvm_argInt_mips_o32(in_self, * (DCint*) &x );
80
+ dc_callvm_argInt_mips_o32(in_self, *(DCint*)&x);
81
81
  }
82
82
 
83
83
  static void dc_callvm_argBool_mips_o32(DCCallVM* in_self, DCbool x)
@@ -100,51 +100,56 @@ static void dc_callvm_argLong_mips_o32(DCCallVM* in_self, DClong x)
100
100
  dc_callvm_argInt_mips_o32(in_self, (DCint)x);
101
101
  }
102
102
 
103
- static void dc_callvm_argLongLong_mips_o32(DCCallVM* in_self, DClonglong Lv)
103
+ static void dc_callvm_argLongLong_mips_o32(DCCallVM* in_self, DClonglong x)
104
104
  {
105
105
  DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
106
-
106
+
107
107
  /* 64-bit values need to be aligned on 8 byte boundaries */
108
108
  dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4);
109
- dcVecAppend(&self->mVecHead, &Lv, sizeof(DClonglong));
110
- self->mArgCount += 1;
109
+ dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong));
110
+ self->mArgCount++;
111
111
  }
112
112
 
113
113
  static void dc_callvm_argFloat_mips_o32(DCCallVM* in_self, DCfloat x)
114
114
  {
115
115
  DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
116
116
 
117
- dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat) );
117
+ dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat));
118
+
119
+ #if defined(DC__ABI_HARDFLOAT)
118
120
  if (self->mArgCount < 2) {
119
- #if defined(DC__Endian_LITTLE)
121
+ /* @@@ unsure if we should zero init, here; seems to work as-is */
122
+ # if defined(DC__Endian_LITTLE)
120
123
  self->mRegData.u[self->mArgCount].f[0] = x;
121
- #else
122
- self->mRegData.u[self->mArgCount].f[1] = x;
123
- #endif
124
- #if 0
124
+ # else
125
+ self->mRegData.u[self->mArgCount].f[1] = x; // floats in regs always right justified
126
+ # endif
127
+ # if 0
125
128
  self->mRegData.u[self->mArgCount].f[1] = x;
126
129
  call kernel
127
130
 
128
- mips:
129
- lwc1 $f12, 4($5) <--- byte offset 4
130
- lwc1 $f13, 0($5)
131
- lwc1 $f14, 12($5) <--- byte offset 12
132
- lwc1 $f15, 8($5)
133
- mipsel:
134
- lwc1 $f12, 0($5) <--- byte offset 4
135
- lwc1 $f13, 4($5)
136
- lwc1 $f14, 8($5) <--- byte offset 12
137
- lwc1 $f15, 12($5)
138
-
139
- #if defined(DC__Endian_LITTLE)
131
+ mips:
132
+ lwc1 $f12, 4($5) <--- byte offset 4
133
+ lwc1 $f13, 0($5)
134
+ lwc1 $f14, 12($5) <--- byte offset 12
135
+ lwc1 $f15, 8($5)
136
+ mipsel:
137
+ lwc1 $f12, 0($5) <--- byte offset 4
138
+ lwc1 $f13, 4($5)
139
+ lwc1 $f14, 8($5) <--- byte offset 12
140
+ lwc1 $f15, 12($5)
141
+
142
+ # if defined(DC__Endian_LITTLE)
140
143
  /* index 0 and 2 */
141
144
  self->mRegData.floats[self->mArgCount*2] = x;
142
- #else
145
+ # else
143
146
  /* index 1 and 3 */
144
147
  self->mRegData.floats[self->mArgCount*2+1] = x;
145
- #endif
146
- #endif
148
+ # endif
149
+ # endif
147
150
  }
151
+ #endif /* DC__ABI_HARDFLOAT */
152
+
148
153
  self->mArgCount++;
149
154
  }
150
155
 
@@ -153,9 +158,13 @@ static void dc_callvm_argDouble_mips_o32(DCCallVM* in_self, DCdouble x)
153
158
  DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
154
159
  /* 64-bit values need to be aligned on 8 byte boundaries */
155
160
  dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4);
156
- dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble) );
161
+ dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
162
+
163
+ #if defined(DC__ABI_HARDFLOAT)
157
164
  if (self->mArgCount < 2)
158
165
  self->mRegData.u[self->mArgCount].d = x;
166
+ #endif /* DC__ABI_HARDFLOAT */
167
+
159
168
  self->mArgCount++;
160
169
  }
161
170
 
@@ -163,11 +172,9 @@ static void dc_callvm_argDouble_mips_o32(DCCallVM* in_self, DCdouble x)
163
172
  void dc_callvm_call_mips_o32(DCCallVM* in_self, DCpointer target)
164
173
  {
165
174
  DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
166
- /* at minimum provide 16-bytes
167
- which hold the first four integer register as spill area
168
- and are automatically loaded to $4-$7
169
- */
170
175
 
176
+ /* provide multiple of 8 (reflecting stack area alignment requirement), and
177
+ minimum of 16-bytes (to hold first 4 int regis as spill area ($4-$7)) */
171
178
  size_t size = DC_MAX(16, ( ( (unsigned) dcVecSize(&self->mVecHead) ) +7UL ) & (-8UL) );
172
179
 
173
180
  dcCall_mips_o32(target, &self->mRegData, size, dcVecData(&self->mVecHead));
@@ -0,0 +1,247 @@
1
+ /*
2
+
3
+ Package: dyncall
4
+ Library: dyncall
5
+ File: dyncall/dyncall_callvm_mips_o32.c
6
+ Description: mips "o32" ABI callvm implementation
7
+ License:
8
+
9
+ Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
10
+ Tassilo Philipp <tphilipp@potion-studios.com>
11
+
12
+ Permission to use, copy, modify, and distribute this software for any
13
+ purpose with or without fee is hereby granted, provided that the above
14
+ copyright notice and this permission notice appear in all copies.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
+
24
+ */
25
+
26
+
27
+
28
+ /*
29
+
30
+ dyncall callvm for mips o32 abi
31
+
32
+ REVISION
33
+ 2010/06/03 initial
34
+
35
+ NOTES:
36
+ we need an argument counter for supporting floating point arguments
37
+ correctly.
38
+
39
+ first two (if any) double/float arguments are mapped via a common structure --
40
+ code must take care to write the right float argument indices which
41
+ differs on C and Assembly-side depending on endianness. (therefore
42
+ both sources have two variants 'mipseb' and 'mipsel'.)
43
+ (only for the first two float/double arguments) see float/double handling
44
+
45
+ although, the abi does not expect usage of floats if first argument is
46
+ not floating point, the call kernel can be used universal for all cases.
47
+
48
+ */
49
+
50
+
51
+ #include "dyncall_callvm_mips_o32.h"
52
+ #include "dyncall_alloc.h"
53
+ #include "dyncall_utils.h"
54
+
55
+
56
+ static void dc_callvm_reset_mips_o32(DCCallVM* in_self)
57
+ {
58
+ DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
59
+ dcVecReset(&self->mVecHead);
60
+ self->mArgCount = 0;
61
+ }
62
+
63
+
64
+ static void dc_callvm_free_mips_o32(DCCallVM* in_self)
65
+ {
66
+ dcFreeMem(in_self);
67
+ }
68
+
69
+ /* arg int -- fillup integer register file OR push on stack */
70
+
71
+ static void dc_callvm_argInt_mips_o32(DCCallVM* in_self, DCint i)
72
+ {
73
+ DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
74
+ dcVecAppend(&self->mVecHead, &i, sizeof(DCint));
75
+ self->mArgCount++;
76
+ }
77
+
78
+ static void dc_callvm_argPointer_mips_o32(DCCallVM* in_self, DCpointer x)
79
+ {
80
+ dc_callvm_argInt_mips_o32(in_self, *(DCint*)&x);
81
+ }
82
+
83
+ static void dc_callvm_argBool_mips_o32(DCCallVM* in_self, DCbool x)
84
+ {
85
+ dc_callvm_argInt_mips_o32(in_self, (DCint)x);
86
+ }
87
+
88
+ static void dc_callvm_argChar_mips_o32(DCCallVM* in_self, DCchar x)
89
+ {
90
+ dc_callvm_argInt_mips_o32(in_self, (DCint)x);
91
+ }
92
+
93
+ static void dc_callvm_argShort_mips_o32(DCCallVM* in_self, DCshort x)
94
+ {
95
+ dc_callvm_argInt_mips_o32(in_self, (DCint)x);
96
+ }
97
+
98
+ static void dc_callvm_argLong_mips_o32(DCCallVM* in_self, DClong x)
99
+ {
100
+ dc_callvm_argInt_mips_o32(in_self, (DCint)x);
101
+ }
102
+
103
+ static void dc_callvm_argLongLong_mips_o32(DCCallVM* in_self, DClonglong x)
104
+ {
105
+ DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
106
+
107
+ /* 64-bit values need to be aligned on 8 byte boundaries */
108
+ dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4);
109
+ dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong));
110
+ self->mArgCount++;
111
+ }
112
+
113
+ static void dc_callvm_argFloat_mips_o32(DCCallVM* in_self, DCfloat x)
114
+ {
115
+ DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
116
+
117
+ dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat));
118
+
119
+ #if defined(DC__ABI_HARDFLOAT)
120
+ if (self->mArgCount < 2) {
121
+ /* @@@ unsure if we should zero init, here; seems to work as-is */
122
+ # if defined(DC__Endian_LITTLE)
123
+ self->mRegData.u[self->mArgCount].f[0] = x;
124
+ # else
125
+ self->mRegData.u[self->mArgCount].f[1] = x; // floats in regs always right justified
126
+ # endif
127
+ # if 0
128
+ self->mRegData.u[self->mArgCount].f[1] = x;
129
+ call kernel
130
+
131
+ mips:
132
+ lwc1 $f12, 4($5) <--- byte offset 4
133
+ lwc1 $f13, 0($5)
134
+ lwc1 $f14, 12($5) <--- byte offset 12
135
+ lwc1 $f15, 8($5)
136
+ mipsel:
137
+ lwc1 $f12, 0($5) <--- byte offset 4
138
+ lwc1 $f13, 4($5)
139
+ lwc1 $f14, 8($5) <--- byte offset 12
140
+ lwc1 $f15, 12($5)
141
+
142
+ # if defined(DC__Endian_LITTLE)
143
+ /* index 0 and 2 */
144
+ self->mRegData.floats[self->mArgCount*2] = x;
145
+ # else
146
+ /* index 1 and 3 */
147
+ self->mRegData.floats[self->mArgCount*2+1] = x;
148
+ # endif
149
+ # endif
150
+ }
151
+ #endif /* DC__ABI_HARDFLOAT */
152
+
153
+ self->mArgCount++;
154
+ }
155
+
156
+ static void dc_callvm_argDouble_mips_o32(DCCallVM* in_self, DCdouble x)
157
+ {
158
+ DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
159
+ /* 64-bit values need to be aligned on 8 byte boundaries */
160
+ dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4);
161
+ dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
162
+
163
+ #if defined(DC__ABI_HARDFLOAT)
164
+ if (self->mArgCount < 2)
165
+ self->mRegData.u[self->mArgCount].d = x;
166
+ #endif /* DC__ABI_HARDFLOAT */
167
+
168
+ self->mArgCount++;
169
+ }
170
+
171
+ /* Call. */
172
+ void dc_callvm_call_mips_o32(DCCallVM* in_self, DCpointer target)
173
+ {
174
+ DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
175
+ /* at minimum provide 16-bytes
176
+ which hold the first four integer register as spill area
177
+ and are automatically loaded to $4-$7
178
+ */
179
+
180
+ size_t size = DC_MAX(16, ( ( (unsigned) dcVecSize(&self->mVecHead) ) +7UL ) & (-8UL) );
181
+
182
+ dcCall_mips_o32(target, &self->mRegData, size, dcVecData(&self->mVecHead));
183
+ }
184
+
185
+ static void dc_callvm_mode_mips_o32(DCCallVM* in_self, DCint mode);
186
+
187
+ DCCallVM_vt gVT_mips_o32 =
188
+ {
189
+ &dc_callvm_free_mips_o32
190
+ , &dc_callvm_reset_mips_o32
191
+ , &dc_callvm_mode_mips_o32
192
+ , &dc_callvm_argBool_mips_o32
193
+ , &dc_callvm_argChar_mips_o32
194
+ , &dc_callvm_argShort_mips_o32
195
+ , &dc_callvm_argInt_mips_o32
196
+ , &dc_callvm_argLong_mips_o32
197
+ , &dc_callvm_argLongLong_mips_o32
198
+ , &dc_callvm_argFloat_mips_o32
199
+ , &dc_callvm_argDouble_mips_o32
200
+ , &dc_callvm_argPointer_mips_o32
201
+ , NULL /* argStruct */
202
+ , (DCvoidvmfunc*) &dc_callvm_call_mips_o32
203
+ , (DCboolvmfunc*) &dc_callvm_call_mips_o32
204
+ , (DCcharvmfunc*) &dc_callvm_call_mips_o32
205
+ , (DCshortvmfunc*) &dc_callvm_call_mips_o32
206
+ , (DCintvmfunc*) &dc_callvm_call_mips_o32
207
+ , (DClongvmfunc*) &dc_callvm_call_mips_o32
208
+ , (DClonglongvmfunc*) &dc_callvm_call_mips_o32
209
+ , (DCfloatvmfunc*) &dc_callvm_call_mips_o32
210
+ , (DCdoublevmfunc*) &dc_callvm_call_mips_o32
211
+ , (DCpointervmfunc*) &dc_callvm_call_mips_o32
212
+ , NULL /* callStruct */
213
+ };
214
+
215
+ /* mode: only a single mode available currently. */
216
+ static void dc_callvm_mode_mips_o32(DCCallVM* in_self, DCint mode)
217
+ {
218
+ DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
219
+ DCCallVM_vt* vt;
220
+
221
+ switch(mode) {
222
+ case DC_CALL_C_DEFAULT:
223
+ case DC_CALL_C_MIPS32_O32:
224
+ case DC_CALL_C_ELLIPSIS:
225
+ case DC_CALL_C_ELLIPSIS_VARARGS:
226
+ vt = &gVT_mips_o32;
227
+ break;
228
+ default:
229
+ self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
230
+ return;
231
+ }
232
+ dc_callvm_base_init(&self->mInterface, vt);
233
+ }
234
+
235
+ /* Public API. */
236
+ DCCallVM* dcNewCallVM(DCsize size)
237
+ {
238
+ DCCallVM_mips_o32* p = (DCCallVM_mips_o32*)dcAllocMem(sizeof(DCCallVM_mips_o32)+size);
239
+
240
+ dc_callvm_mode_mips_o32((DCCallVM*)p, DC_CALL_C_DEFAULT);
241
+
242
+ dcVecInit(&p->mVecHead, size);
243
+ dc_callvm_reset_mips_o32((DCCallVM*)p);
244
+
245
+ return (DCCallVM*)p;
246
+ }
247
+