1{
2
3    This file is part of the Free Pascal run time library.
4    Copyright (c) 2011 by the Free Pascal development team.
5
6    Processor dependent implementation for the system unit for
7    JVM
8
9    See the file COPYING.FPC, included in this distribution,
10    for details about the copyright.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 **********************************************************************}
17
18
19{****************************************************************************
20                           JVM specific stuff
21****************************************************************************}
22
23{$define FPC_SYSTEM_HAS_SYSINITFPU}
24Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
25  begin
26    softfloat_exception_mask:=[float_flag_underflow, float_flag_inexact, float_flag_denormal];
27  end;
28
29{$define FPC_SYSTEM_HAS_SYSRESETFPU}
30Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
31  begin
32    softfloat_exception_flags:=[];
33  end;
34
35
36procedure fpc_cpuinit;
37  begin
38    SysResetFPU;
39    if not(IsLibrary) then
40      SysInitFPU;
41  end;
42
43
44{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
45function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;
46  begin
47    result:=nil;
48  end;
49
50
51{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
52function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;
53  begin
54    result:=nil;
55  end;
56
57
58{$define FPC_SYSTEM_HAS_SPTR}
59function Sptr:Pointer;
60   begin
61     result:=nil;
62   end;
63
64{****************************************************************************
65                               Primitives
66****************************************************************************}
67
68{ lie so that the non-compilable generic versions will be skipped }
69{$define FPC_SYSTEM_HAS_MOVE}
70{$define FPC_SYSTEM_HAS_FILLCHAR}
71
72{$push}
73{$q-,r-}
74
75procedure fillchar(var arr: array of jbyte; len: sizeint; val: byte);
76  begin
77    JUArrays.fill(arr,0,len,jbyte(val));
78  end;
79
80{ boolean maps to a different signature }
81procedure fillchar(var arr: array of jbyte; len: sizeint; val: jboolean);
82  begin
83    JUArrays.fill(arr,0,len,jbyte(val));
84  end;
85
86{ don't define since the signature would be the same as the one above (well,
87  we could cheat by changing the case since the JVM is case-sensitive, but
88  this way we also save on code size) -> map it to the byte version via
89  "external" }
90
91procedure fillchar(var arr: array of boolean; len: sizeint; val: byte);
92  begin
93    JUArrays.fill(TJBooleanArray(@arr),0,len,jboolean(val));
94  end;
95
96procedure fillchar(var arr: array of boolean; len: sizeint; val: boolean);
97  begin
98    JUArrays.fill(TJBooleanArray(@arr),0,len,val);
99  end;
100
101
102procedure fillchar(var arr: array of jshort; len: sizeint; val: byte);
103  var
104    w: jshort;
105  begin
106    w:=(val shl 8) or val;
107    JUArrays.fill(arr,0,len div 2,w);
108    if (len and 1) <> 0 then
109      arr[len div 2 + 1]:=(arr[len div 2 + 1] and $ff) or (val shl 8);
110  end;
111
112procedure fillchar(var arr: array of jshort; len: sizeint; val: boolean);
113  begin
114    fillchar(arr,len,jbyte(val));
115  end;
116
117{ widechar maps to a different signature }
118procedure fillchar(var arr: array of widechar; len: sizeint; val: byte);
119  var
120    w: widechar;
121  begin
122    w:=widechar((val shl 8) or val);
123    JUArrays.fill(arr,0,len div 2,w);
124    { jvm is big endian -> set top byte of last word }
125    if (len and 1) <> 0 then
126      arr[len shr 1+1]:=widechar((ord(arr[len shr 1+1]) and $ff) or (val shl 8));
127  end;
128
129procedure fillchar(var arr: array of widechar; len: sizeint; val: boolean);
130  begin
131    fillchar(arr,len,byte(val));
132  end;
133
134procedure fillchar(var arr: array of jint; len: sizeint; val: byte);
135  var
136    d, dmask: jint;
137  begin
138    d:=(val shl 8) or val;
139    d:=(d shl 16) or d;
140    JUArrays.fill(arr,0,len div 4,d);
141    len:=len and 3;
142    if len<>0 then
143      begin
144        dmask:=not((1 shl (32-8*len))-1);
145        d:=d and dmask;
146        arr[len shr 2+1]:=(arr[len shr 2+1] and not(dmask)) or d;
147      end;
148  end;
149
150procedure fillchar(var arr: array of jint; len: sizeint; val: boolean);
151  begin
152    fillchar(arr,len,jbyte(val));
153  end;
154
155
156procedure fillchar(var arr: array of jlong; len: sizeint; val: byte);
157  var
158    i, imask: jlong;
159  begin
160    i:=(val shl 8) or val;
161    i:=cardinal(i shl 16) or i;
162    i:=(i shl 32) or i;
163    JUArrays.fill(arr,0,len shr 3,i);
164    len:=len and 7;
165    if len<>0 then
166      begin
167        imask:=not((jlong(1) shl (64-8*len))-1);
168        i:=i and imask;
169        arr[len shr 3+1]:=(arr[len shr 3+1] and not(imask)) or i;
170      end;
171  end;
172
173procedure fillchar(var arr: array of jlong; len: sizeint; val: boolean);
174  begin
175    fillchar(arr,len,jbyte(val));
176  end;
177
178{$pop}
179
180{$define FPC_SYSTEM_HAS_FILLWORD}
181{$define FPC_SYSTEM_HAS_FILLDWORD}
182{$define FPC_SYSTEM_HAS_FILLQWORD}
183
184{$define FPC_SYSTEM_HAS_INDEXBYTE}
185
186function  IndexByte(const buf: array of jbyte;len:SizeInt;b:jbyte):SizeInt;
187  var
188    i: SizeInt;
189  begin
190    if len<0 then
191      len:=high(buf)+1;
192    for i:=0 to len-1 do
193      if buf[i]=b then
194        exit(i);
195    IndexByte:=-1;
196  end;
197
198
199function  IndexByte(const buf: array of boolean;len:SizeInt;b:jbyte):SizeInt;
200var
201  i: SizeInt;
202begin
203  if len<0 then
204    len:=high(buf)+1;
205  for i:=0 to len-1 do
206    if jbyte(buf[i])=b then
207      exit(i);
208  IndexByte:=-1;
209end;
210
211
212function  IndexChar(const buf: array of boolean;len:SizeInt;b:ansichar):SizeInt;
213  begin
214    IndexChar:=IndexByte(buf,len,jbyte(b));
215  end;
216
217
218function  IndexChar(const buf: array of jbyte;len:SizeInt;b:ansichar):SizeInt;
219begin
220  IndexChar:=IndexByte(buf,len,jbyte(b));
221end;
222
223{$define FPC_SYSTEM_HAS_INDEXWORD}
224
225function  IndexWord(const buf: array of jshort;len:SizeInt;b:jshort):SizeInt;
226  var
227    i: SizeInt;
228  begin
229    if len<0 then
230      len:=high(buf)+1;
231    for i:=0 to len-1 do
232      if buf[i]=b then
233        exit(i);
234    IndexWord:=-1;
235  end;
236
237
238function  IndexWord(const buf: array of jchar;len:SizeInt;b:jchar):SizeInt;
239  var
240    i: SizeInt;
241  begin
242    if len<0 then
243      len:=high(buf)+1;
244    for i:=0 to len-1 do
245      if buf[i]=b then
246        exit(i);
247    IndexWord:=-1;
248  end;
249
250function  IndexWord(const buf: array of jchar;len:SizeInt;b:jshort):SizeInt;
251  var
252    i: SizeInt;
253    c: jchar;
254  begin
255    c:=jchar(b);
256    if len<0 then
257      len:=high(buf)+1;
258    for i:=0 to len-1 do
259      if buf[i]=c then
260        exit(i);
261    IndexWord:=-1;
262  end;
263
264{$define FPC_SYSTEM_HAS_INDEXDWORD}
265{$define FPC_SYSTEM_HAS_INDEXQWORD}
266{$define FPC_SYSTEM_HAS_COMPAREBYTE}
267{$define FPC_SYSTEM_HAS_COMPAREWORD}
268{$define FPC_SYSTEM_HAS_COMPAREDWORD}
269{$define FPC_SYSTEM_HAS_MOVECHAR0}
270{$define FPC_SYSTEM_HAS_INDEXCHAR0}
271{$define FPC_SYSTEM_HAS_COMPARECHAR0}
272
273{****************************************************************************
274                                 String
275****************************************************************************}
276
277{$define FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
278
279function fpc_pchar_length(p:pchar):sizeint;[public,alias:'FPC_PCHAR_LENGTH']; compilerproc;
280begin
281  if assigned(p) then
282    Result:=IndexByte(TAnsiCharArray(p),high(Result),0)
283  else
284    Result:=0;
285end;
286
287
288{$define FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
289procedure fpc_pchar_to_shortstr(out res : shortstring;p:pchar); compilerproc;
290var
291  i, len: longint;
292  arr: TAnsiCharArray;
293begin
294  arr:=TAnsiCharArray(p);
295  i:=0;
296  while arr[i]<>#0 do
297    inc(i);
298  if i<>0 then
299    res:=pshortstring(ShortStringClass.create(arr,min(i,high(res))))^
300  else
301    res:=''
302end;
303
304
305{$define FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
306procedure fpc_shortstr_to_shortstr(out res:shortstring; const sstr: shortstring); compilerproc;
307var
308  len: longint;
309begin
310  len:=length(sstr);
311  if len>high(res) then
312    len:=high(res);
313  ShortstringClass(@res).curlen:=len;
314  if len>0 then
315    JLSystem.ArrayCopy(JLObject(ShortstringClass(@sstr).fdata),0,JLObject(ShortstringClass(@res).fdata),0,len);
316end;
317
318
319{$define FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
320procedure fpc_shortstr_append_shortstr(var s1:shortstring;const s2:shortstring); compilerproc;
321var
322  s1l, s2l : integer;
323begin
324  s1l:=length(s1);
325  s2l:=length(s2);
326  if s1l+s2l>high(s1) then
327    s2l:=high(s1)-s1l;
328  if s2l>0 then
329    JLSystem.ArrayCopy(JLObject(ShortstringClass(@s2).fdata),0,JLObject(ShortstringClass(@s1).fdata),s1l,s2l);
330  s1[0]:=chr(s1l+s2l);
331end;
332
333
334{$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
335function fpc_shortstr_compare(const left,right:shortstring) : longint; compilerproc;
336Var
337  MaxI,Temp, i : SizeInt;
338begin
339  if ShortstringClass(@left)=ShortstringClass(@right) then
340    begin
341      result:=0;
342      exit;
343    end;
344  Maxi:=Length(left);
345  temp:=Length(right);
346  If MaxI>Temp then
347    MaxI:=Temp;
348  if MaxI>0 then
349    begin
350      for i:=0 to MaxI-1 do
351        begin
352          result:=ord(ShortstringClass(@left).fdata[i])-ord(ShortstringClass(@right).fdata[i]);
353          if result<>0 then
354            exit;
355        end;
356      result:=Length(left)-Length(right);
357    end
358  else
359    result:=Length(left)-Length(right);
360end;
361
362
363{$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE_EQUAL}
364
365function fpc_shortstr_compare_intern(const left,right:shortstring) : longint; external name 'fpc_shortstr_compare';
366
367function fpc_shortstr_compare_equal(const left,right:shortstring) : longint; compilerproc;
368begin
369  { perform normal comparsion, because JUArrays.equals() only returns true if
370    the arrays have equal length, while we only want to compare curlen bytes }
371  result:=fpc_shortstr_compare_intern(left,right);
372end;
373
374
375{$define FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
376procedure fpc_chararray_to_shortstr(out res : shortstring;const arr: array of AnsiChar; zerobased: boolean = true); compilerproc;
377var
378 l: longint;
379 index: longint;
380 len: byte;
381 foundnull: boolean;
382begin
383  l:=high(arr)+1;
384  if l>=high(res)+1 then
385    l:=high(res)
386  else if l<0 then
387    l:=0;
388  if zerobased then
389    begin
390      foundnull:=false;
391      index:=0;
392      for index:=low(arr) to l-1 do
393        if arr[index]=#0 then
394          begin
395            foundnull:=true;
396            break;
397          end;
398      if not foundnull then
399        len:=l
400      else
401        len:=index;
402    end
403  else
404    len:=l;
405  if len>0 then
406    JLSystem.ArrayCopy(JLObject(@arr),0,JLObject(ShortstringClass(@res).fdata),0,len);
407  ShortstringClass(@res).curlen:=len;
408end;
409
410
411{$define FPC_SYSTEM_HAS_FPC_SHORTSTR_TO_CHARARRAY}
412procedure fpc_shortstr_to_chararray(out res: array of AnsiChar; const src: ShortString); compilerproc;
413var
414  len: longint;
415begin
416  len:=length(src);
417  if len>length(res) then
418    len:=length(res);
419  { make sure we don't access char 1 if length is 0 (JM) }
420  if len>0 then
421    JLSystem.ArrayCopy(JLObject(ShortstringClass(@src).fdata),0,JLObject(@res),0,len);
422  if len<=high(res) then
423    JUArrays.fill(TJByteArray(@res),len,high(res),0);
424end;
425
426
427{****************************************************************************
428                                 Str()
429****************************************************************************}
430
431{$define FPC_SYSTEM_HAS_INT_STR_LONGINT}
432procedure int_str(l:longint;out s:shortstring);
433  begin
434    s:=unicodestring(JLInteger.valueOf(l).toString);
435  end;
436
437
438{$define FPC_SYSTEM_HAS_INT_STR_LONGWORD}
439procedure int_str_unsigned(l:longword;out s:shortstring);
440  begin
441    s:=unicodestring(JLLong.valueOf(l).toString);
442  end;
443
444
445{$define FPC_SYSTEM_HAS_INT_STR_INT64}
446procedure int_str(l:int64;out s:shortstring);
447  begin
448    s:=unicodestring(JLLong.valueOf(l).toString);
449  end;
450
451
452{$define FPC_SYSTEM_HAS_INT_STR_QWORD}
453procedure int_str_unsigned(l:qword;out s:shortstring);
454var
455  tmp: int64;
456  tmpstr: JLString;
457  bi: JMBigInteger;
458begin
459  tmp:=int64(l);
460  tmpstr:=JLLong.valueOf(tmp and $7fffffffffffffff).toString;
461  if tmp<0 then
462    begin
463      { no unsigned 64 bit types in Java -> use big integer to add
464        high(int64) to the string representation }
465      bi:=JMBigInteger.Create(tmpstr);
466      bi:=bi.add(JMBigInteger.Create('9223372036854775808'));
467      tmpstr:=bi.toString;
468    end;
469  s:=unicodestring(tmpstr);
470end;
471
472
473{ lies... }
474{$define FPC_SYSTEM_HAS_ODD_LONGWORD}
475{$define FPC_SYSTEM_HAS_ODD_QWORD}
476{$define FPC_SYSTEM_HAS_SQR_QWORD}
477
478