|
@@ -73,6 +73,7 @@ interface
|
|
function get_internal_data_section_internal_label: tasmlabel; override;
|
|
function get_internal_data_section_internal_label: tasmlabel; override;
|
|
public
|
|
public
|
|
destructor destroy; override;
|
|
destructor destroy; override;
|
|
|
|
+ procedure emit_tai(p: tai; def: tdef); override;
|
|
procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); override;
|
|
procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); override;
|
|
procedure emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef); override;
|
|
procedure emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef); override;
|
|
procedure queue_init(todef: tdef); override;
|
|
procedure queue_init(todef: tdef); override;
|
|
@@ -90,9 +91,9 @@ interface
|
|
implementation
|
|
implementation
|
|
|
|
|
|
uses
|
|
uses
|
|
- verbose,
|
|
|
|
|
|
+ verbose,systems,
|
|
aasmdata,
|
|
aasmdata,
|
|
- cpubase,llvmbase,
|
|
|
|
|
|
+ cpubase,cpuinfo,llvmbase,
|
|
symbase,symtable,llvmdef,defutil;
|
|
symbase,symtable,llvmdef,defutil;
|
|
|
|
|
|
{ tllvmaggregateinformation }
|
|
{ tllvmaggregateinformation }
|
|
@@ -167,6 +168,22 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ procedure tllvmtai_typedconstbuilder.emit_tai(p: tai; def: tdef);
|
|
|
|
+ var
|
|
|
|
+ arrdef: tdef;
|
|
|
|
+ begin
|
|
|
|
+ { inside an aggregate, an 80 bit floating point number must be
|
|
|
|
+ emitted as an array of 10 bytes to prevent ABI alignment and
|
|
|
|
+ padding to 16 bytes }
|
|
|
|
+ if (def.typ=floatdef) and
|
|
|
|
+ (tfloatdef(def).floattype=s80real) and
|
|
|
|
+ assigned(curagginfo) then
|
|
|
|
+ do_emit_extended_in_aggregate(p)
|
|
|
|
+ else
|
|
|
|
+ inherited;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
procedure tllvmtai_typedconstbuilder.do_emit_tai(p: tai; def: tdef);
|
|
procedure tllvmtai_typedconstbuilder.do_emit_tai(p: tai; def: tdef);
|
|
var
|
|
var
|
|
ai: tai;
|
|
ai: tai;
|
|
@@ -342,6 +359,38 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ procedure tllvmtai_typedconstbuilder.do_emit_extended_in_aggregate(p: tai);
|
|
|
|
+ type
|
|
|
|
+ p80realval =^t80realval;
|
|
|
|
+ t80realval = packed record
|
|
|
|
+ case byte of
|
|
|
|
+ 0: (v: ts80real);
|
|
|
|
+ 1: (a: array[0..9] of byte);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ var
|
|
|
|
+ arrdef: tdef;
|
|
|
|
+ i: longint;
|
|
|
|
+ realval: p80realval;
|
|
|
|
+ begin
|
|
|
|
+ { emit as an array of 10 bytes }
|
|
|
|
+ arrdef:=carraydef.getreusable(u8inttype,10);
|
|
|
|
+ maybe_begin_aggregate(arrdef);
|
|
|
|
+ if (p.typ<>ait_realconst) then
|
|
|
|
+ internalerror(2015062401);
|
|
|
|
+ realval:=p80realval(@tai_realconst(p).value.s80val);
|
|
|
|
+ if target_info.endian=source_info.endian then
|
|
|
|
+ for i:=0 to 9 do
|
|
|
|
+ emit_tai(tai_const.Create_8bit(realval^.a[i]),u8inttype)
|
|
|
|
+ else
|
|
|
|
+ for i:=9 downto 0 do
|
|
|
|
+ emit_tai(tai_const.Create_8bit(realval^.a[i]),u8inttype);
|
|
|
|
+ maybe_end_aggregate(arrdef);
|
|
|
|
+ { free the original constant, since we didn't emit it }
|
|
|
|
+ p.free;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
procedure tllvmtai_typedconstbuilder.queue_init(todef: tdef);
|
|
procedure tllvmtai_typedconstbuilder.queue_init(todef: tdef);
|
|
begin
|
|
begin
|
|
inherited;
|
|
inherited;
|