Bonsoir, je suis entrain de porter ma bibliothèques sur les vecteurs, matrices ect... réalisée avec Lazarus vers Delphi. Je suis confronté à un problème.
Par exemple :
Ces deux méthodes fonctionnent parfaitement sous Lazarus que ce soit en 32 ou 64 bits
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 function get_mxcsr:dword; var _flags:dword; begin asm stmxcsr _flags end; get_mxcsr:=_flags; end; procedure set_mxcsr(flags:dword); var _flags:dword; begin _flags:=flags; asm ldmxcsr _flags end; end;
Sous Delphi elles fonctionnent en 32 bits
Mais en 64 bits le compilateur me renvoie l'erreur suivante : [dcc64 Erreur] beanz.vectormath.pas(3274): E1025 Fonctionnalité de langage non supportée : 'ASM'
En 64 bits il semblerai que l'utilisation d'un bloc assembleur dans une méthode, qui n'est pas codée 100% en assembleur soit impossible. Savez vous si il existe une directive ou options de compilation à déclarer ou est ce une limitation due Delphi lui même.
Au pire je pense arriver à me passer de ces deux méthodes en faisant autrement.
dans le même style
j'ai en 32 bits cette fonction
que j'ai du séparer en deux pour qu'elle fonctionne en 64bits :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 function TBZVector4f.AngleBetween(Const A, ACenterPoint : TBZVector4f): Single; Var vResult : Single; begin asm movups xmm0, [EAX] mov ecx, [A] // A is a pointer on the stack movups xmm1, [ecx] mov ecx, [ACenterPoint] // ACenterPoint is a pointer on the stack movups xmm2, [ecx] subps xmm0, xmm2 subps xmm1, xmm2 // Normalize xmm0 result in xmm2 movups xmm3, xmm0 andps xmm3, [cSSE_MASK_ONLY_W] andps xmm0, [cSSE_MASK_NO_W] movups xmm2, xmm0 {$IFDEF USE_ASM_SSE_3} mulps xmm0, xmm0 haddps xmm0, xmm0 haddps xmm0, xmm0 {$ELSE} mulps xmm0, xmm0 movups xmm5, xmm0 shufps xmm0, xmm5, $4e addps xmm0, xmm5 movups xmm5, xmm0 shufps xmm5, xmm5, $11 addps xmm0, xmm5 {$ENDIF} {$IFDEF USE_ASM_SIMD_HIGHPRECISION} // High Precision sqrtps xmm0, xmm0 divps xmm2, xmm0 {$ELSE} // Low precision rsqrtps xmm0, xmm0 //approximate reciprocal mulps xmm2, xmm0 {$ENDIF} addps xmm2, xmm3 // Normalize xmm1 result in xmm4 movups xmm3, xmm1 andps xmm3, [cSSE_MASK_ONLY_W] andps xmm1, [cSSE_MASK_NO_W] movups xmm4, xmm1 {$IFDEF USE_ASM_SSE_3} mulps xmm1, xmm1 haddps xmm1, xmm1 haddps xmm1, xmm1 {$ELSE} mulps xmm1, xmm1 movups xmm5, xmm1 shufps xmm1, xmm5, $4e addps xmm1, xmm5 movups xmm5, xmm1 shufps xmm5, xmm5, $11 addps xmm1, xmm5 {$ENDIF} {$IFDEF USE_ASM_SIMD_HIGHPRECISION} // High Precision sqrtps xmm1, xmm1 divps xmm4, xmm1 {$ELSE} // Low precision rsqrtps xmm1, xmm1 //approximate reciprocal mulps xmm4, xmm1 {$ENDIF} addps xmm4,xmm3 // AngleCosine movups xmm1, xmm4 movups xmm0, xmm2 // Copy A // DotProd xmm0/xmm1 Result in xmm3 {$IFDEF USE_ASM_SSE_4} dpps xmm0, xmm1, 01110001b //or $F1 movups xmm3, xmm0 {$ELSE} {$IFDEF USE_ASM_SSE_3} andps xmm0, [cSSE_MASK_NO_W] mulps xmm1, xmm0 haddps xmm1, xmm1 haddps xmm1, xmm1 movups xmm3, xmm1 {$ELSE} mulps xmm1, xmm0 movhlps xmm0, xmm1 addps xmm0, xmm1 shufps xmm1, xmm1, 00000001b addps xmm1, xmm0 movups xmm3, xmm1 {$ENDIF} {$ENDIF} // Length xmm2 result in xmm2 andps xmm2, [cSSE_MASK_NO_W] {$IFDEF USE_ASM_SSE_4} dpps xmm2, xmm2, $FF; sqrtss xmm2, xmm2 {$ELSE} mulps xmm2, xmm2 {$IFDEF USE_ASM_SSE_3} haddps xmm2, xmm2 haddps xmm2, xmm2 sqrtss xmm2, xmm2 {$ELSE} movhlps xmm1, xmm2 addss xmm1, xmm2 shufps xmm2, xmm2, $55 addss xmm1, xmm2 sqrtss xmm2, xmm1 {$ENDIF} {$ENDIF} // Lenght xmm4 result in xmm4 andps xmm4, [cSSE_MASK_NO_W] {$IFDEF USE_ASM_SSE_4} dpps xmm4, xmm4, $FF; sqrtss xmm4, xmm4 {$ELSE} mulps xmm4, xmm4 {$IFDEF USE_ASM_SSE_3} haddps xmm4, xmm4 haddps xmm4, xmm4 sqrtss xmm4, xmm4 {$ELSE} movhlps xmm1, xmm4 addss xmm1, xmm4 shufps xmm4, xmm4, $55 addss xmm1, xmm4 sqrtss xmm4, xmm1 {$ENDIF} {$ENDIF} mulps xmm2, xmm4 divps xmm3, xmm2 movss [vResult], xmm3 end; Result := ArcCos(vResult); end;
Sinon me restera la solution de faire une DLL avec Lazarus et de l'importer dans Delphi au pire, mais j'aurais souhaiter éviter.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 function PreComputeAngleBetween(Const A, ACenterPoint : TBZVector4f): Single; register; asm movaps xmm0,[RCX] //self is still in rcx //-------- LAZARUS CODE -------------- // mov rax, DWORD [A] // A is a pointer on the stack // movups xmm1, [RAX] //-------------------------------- movaps xmm1, [A] // DWORD PTR [RAX] //mov rax, [ACenterPoint] // ACenterPoint is a pointer on the stack --> Lazarus movaps xmm2, [ACenterPoint] //DWORD PTR [RAX] subps xmm0, xmm2 subps xmm1, xmm2 // Normalize xmm0 result in xmm2 movaps xmm3,xmm0 andps xmm3, DQWORD PTR [RIP+cSSE_MASK_ONLY_W] andps xmm0, DQWORD PTR [RIP+cSSE_MASK_NO_W] movaps xmm2, xmm0 {$IFDEF USE_ASM_SSE_3} mulps xmm0, xmm0 //haddps xmm0, xmm0 //haddps xmm0, xmm0 movshdup xmm4, xmm0 addps xmm0, xmm1 movhlps xmm4, xmm0 addss xmm0, xmm4 {$ELSE} mulps xmm0, xmm0 movaps xmm5, xmm0 shufps xmm0, xmm5, $4e addps xmm0, xmm5 movaps xmm5, xmm0 shufps xmm5, xmm5, $11 addps xmm0, xmm5 {$ENDIF} {$IFDEF USE_ASM_SIMD_HIGHPRECISION} // High Precision sqrtps xmm0, xmm0 divps xmm2, xmm0 {$ELSE} // Low precision rsqrtps xmm0, xmm0 //approximate reciprocal mulps xmm2, xmm0 {$ENDIF} addps xmm2,xmm3 // Normalize xmm1 result in xmm4 movaps xmm3,xmm1 andps xmm3, DQWORD PTR [RIP+cSSE_MASK_ONLY_W] andps xmm1, DQWORD PTR [RIP+cSSE_MASK_NO_W] movaps xmm4, xmm1 {$IFDEF USE_ASM_SSE_3} mulps xmm1, xmm1 //haddps xmm1, xmm1 //haddps xmm1, xmm1 movshdup xmm5, xmm1 addps xmm1, xmm5 movhlps xmm5, xmm1 addss xmm1, xmm5 {$ELSE} mulps xmm1, xmm1 movaps xmm5, xmm1 shufps xmm1, xmm5, $4e addps xmm1, xmm5 movaps xmm5, xmm1 shufps xmm5, xmm5, $11 addps xmm1, xmm5 {$ENDIF} {$IFDEF USE_ASM_SIMD_HIGHPRECISION} // High Precision sqrtps xmm1, xmm1 divps xmm4, xmm1 {$ELSE} // Low precision rsqrtps xmm1, xmm1 //approximate reciprocal mulps xmm4, xmm1 {$ENDIF} addps xmm4,xmm3 // AngleCosine movaps xmm1, xmm4 movaps xmm0, xmm2 // Copy A // DotProd xmm0/xmm1 Result in xmm3 {$IFDEF USE_ASM_SSE_4} dpps xmm0, xmm1, 01110001b //or $F1 movaps xmm3,xmm0 {$ELSE} {$IFDEF USE_ASM_SSE_3} andps xmm0, DQWORD PTR [RIP+cSSE_MASK_NO_W] mulps xmm1, xmm0 //haddps xmm1, xmm1 //haddps xmm1, xmm1 movshdup xmm0, xmm1 addps xmm1, xmm0 movhlps xmm0, xmm1 addss xmm1, xmm0 movaps xmm3,xmm1 {$ELSE} mulps xmm1, xmm0 movhlps xmm0, xmm1 addps xmm0, xmm1 shufps xmm1, xmm1, 00000001b addps xmm1, xmm0 movaps xmm3, xmm1 {$ENDIF} {$ENDIF} // Length xmm2 result in xmm2 andps xmm5, DQWORD PTR [RIP+cSSE_MASK_NO_W] {$IFDEF USE_ASM_SSE_4} dpps xmm2, xmm2, $FF; sqrtss xmm2, xmm2 {$ELSE} mulps xmm2, xmm2 {$IFDEF USE_ASM_SSE_3} //haddps xmm2, xmm2 //haddps xmm2, xmm2 movshdup xmm5, xmm2 addps xmm2, xmm5 movhlps xmm5, xmm2 addss xmm2, xmm5 sqrtss xmm2, xmm2 {$ELSE} movhlps xmm1, xmm2 addss xmm1, xmm2 shufps xmm2, xmm2, $55 addss xmm1, xmm2 sqrtss xmm2, xmm1 {$ENDIF} {$ENDIF} // Lenght xmm4 result in xmm4 andps xmm4, DQWORD PTR [RIP+cSSE_MASK_NO_W] {$IFDEF USE_ASM_SSE_4} dpps xmm4, xmm4, $FF; sqrtss xmm4, xmm4 {$ELSE} mulps xmm4, xmm4 {$IFDEF USE_ASM_SSE_3} //haddps xmm4, xmm4 //haddps xmm4, xmm4 movshdup xmm5, xmm4 addps xmm4, xmm5 movhlps xmm5, xmm4 addss xmm4, xmm5 sqrtss xmm4, xmm4 {$ELSE} movhlps xmm1, xmm4 addss xmm1, xmm4 shufps xmm4, xmm4, $55 addss xmm1, xmm4 sqrtss xmm4, xmm1 {$ENDIF} {$ENDIF} mulps xmm2,xmm4 divps xmm3, xmm2 movss [Result], xmm3 end; function TBZVector4f.AngleBetween(Const A, ACenterPoint : TBZVector4f): Single; Var vResult : Single; begin vResult := PreComputeAngleBetween(A, ACenterPoint); Result := Beanz.Math.ArcCos(vResult); end;
Avez vous une explication sur ce phénomène ? c'est tout de même très étrange, je trouve.
Note : Je n'ai pas encore fais de test donc ces exemples ne sont par encore viables. Les registres utilisés par Delphi ne sont peut-être (surement) pas tout à fait les mêmes qu'avec Lazarus. Il faut que je trouve un peu de doc sur comment Delphi gère l' ABI.
Merci
Bonne fin de soirée
Partager