rbdc 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+