* fixed several ppc assembler reader related problems

* local vars in assembler procedures now start at offset 4
  * fixed second_int_to_bool (apparently an integer can be in  LOC_JUMP??)
This commit is contained in:
Jonas Maebe 2003-11-29 16:27:19 +00:00
parent 90a0c832e4
commit d5373d5971
10 changed files with 245 additions and 141 deletions

View File

@ -211,12 +211,25 @@ unit agppcgas;
function cond2str(op: tasmop; c: tasmcond): string; function cond2str(op: tasmop; c: tasmcond): string;
{ note: no checking is performed whether the given combination of } { note: no checking is performed whether the given combination of }
{ conditions is valid } { conditions is valid }
var tempstr: string; var
tempstr: string;
begin begin
tempstr:=#9; tempstr:=#9;
case c.simple of case c.simple of
false: cond2str := tempstr+gas_op2str[op]+#9+tostr(c.bo)+','+ false:
tostr(c.bi); begin
cond2str := tempstr+gas_op2str[op];
case c.dirhint of
DH_None:;
DH_Minus:
cond2str:=cond2str+'-';
DH_Plus:
cond2str:=cond2str+'+';
else
internalerror(2003112901);
end;
cond2str:=cond2str++#9+tostr(c.bo)+','+tostr(c.bi);
end;
true: true:
if (op >= A_B) and (op <= A_BCLRL) then if (op >= A_B) and (op <= A_BCLRL) then
case c.cond of case c.cond of
@ -227,7 +240,17 @@ unit agppcgas;
else else
begin begin
tempstr := tempstr+'b'+asmcondflag2str[c.cond]+ tempstr := tempstr+'b'+asmcondflag2str[c.cond]+
branchmode(op)+#9; branchmode(op);
case c.dirhint of
DH_None:
tempstr:=tempstr+#9;
DH_Minus:
tempstr:=cond2str+('-'+#9);
DH_Plus:
tempstr:=tempstr+('+'+#9);
else
internalerror(2003112901);
end;
case c.cond of case c.cond of
C_LT..C_NU: C_LT..C_NU:
cond2str := tempstr+gas_regname(newreg(R_SPECIALREGISTER,c.cr,R_SUBWHOLE)); cond2str := tempstr+gas_regname(newreg(R_SPECIALREGISTER,c.cr,R_SUBWHOLE));
@ -244,10 +267,6 @@ unit agppcgas;
{ case tempstr := 'tw';} { case tempstr := 'tw';}
end; end;
end; end;
case c.dirhint of
DH_Minus:
cond2str:=cond2str+'-';
end;
end; end;
Procedure TPPCGNUAssembler.WriteInstruction(hp : tai); Procedure TPPCGNUAssembler.WriteInstruction(hp : tai);
@ -302,7 +321,12 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.34 2003-11-15 19:00:10 florian Revision 1.35 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.34 2003/11/15 19:00:10 florian
* fixed ppc assembler reader * fixed ppc assembler reader
Revision 1.33 2003/11/12 16:05:40 florian Revision 1.33 2003/11/12 16:05:40 florian

View File

@ -154,7 +154,7 @@ uses
{ conditions when using ctr decrement etc } { conditions when using ctr decrement etc }
C_T,C_F,C_DNZ,C_DNZT,C_DNZF,C_DZ,C_DZT,C_DZF); C_T,C_F,C_DNZ,C_DNZT,C_DNZF,C_DZ,C_DZT,C_DZF);
TDirHint = (DH_None,DH_Minus); TDirHint = (DH_None,DH_Minus,DH_Plus);
const const
{ these are in the XER, but when moved to CR_x they correspond with the } { these are in the XER, but when moved to CR_x they correspond with the }
@ -164,10 +164,10 @@ uses
type type
TAsmCond = packed record TAsmCond = packed record
dirhint : tdirhint;
case simple: boolean of case simple: boolean of
false: (BO, BI: byte); false: (BO, BI: byte);
true: ( true: (
dirhint : tdirhint;
cond: TAsmCondFlag; cond: TAsmCondFlag;
case byte of case byte of
0: (); 0: ();
@ -692,7 +692,12 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.78 2003-11-23 20:00:39 jonas Revision 1.79 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.78 2003/11/23 20:00:39 jonas
* fixed is_condreg * fixed is_condreg
* fixed branch condition parsing in assembler reader * fixed branch condition parsing in assembler reader

View File

@ -46,7 +46,7 @@ unit cpupara;
uses uses
verbose,systems, verbose,systems,
cpuinfo, cpuinfo,procinfo,
rgobj, rgobj,
defutil,symsym; defutil,symsym;
@ -56,13 +56,14 @@ unit cpupara;
result := [RS_R3..RS_R12]; result := [RS_R3..RS_R12];
end; end;
function tppcparamanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset; function tppcparamanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;
begin begin
case target_info.abi of case target_info.abi of
abi_powerpc_aix: abi_powerpc_aix:
result := [RS_F0..RS_F13]; result := [RS_F0..RS_F13];
abi_powerpc_sysv: abi_powerpc_sysv:
{ warning: the 64bit sysv abi also uses RS_F0..RS_F13 like the aix abi above } {$warning: the 64bit sysv abi also uses RS_F0..RS_F13 like the aix abi above }
result := [RS_F0..RS_F8]; result := [RS_F0..RS_F8];
else else
internalerror(2003091401); internalerror(2003091401);
@ -314,9 +315,12 @@ unit cpupara;
end; end;
if side = calleeside then if side = calleeside then
begin begin
{$warning FIXME Calleeside offset needs to be calculated} if (paraloc.loc = LOC_REFERENCE) then
{if (paraloc.loc = LOC_REFERENCE) then begin
paraloc.reference.offset := tvarsym(hp.parasym).adjusted_address;} if (current_procinfo.procdef <> p) then
internalerror(2003112201);
inc(paraloc.reference.offset,current_procinfo.calc_stackframe_size);
end;
end; end;
hp.paraloc[side]:=paraloc; hp.paraloc[side]:=paraloc;
hp:=tparaitem(hp.next); hp:=tparaitem(hp.next);
@ -359,7 +363,12 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.50 2003-10-17 14:52:07 peter Revision 1.51 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.50 2003/10/17 14:52:07 peter
* fixed ppc build * fixed ppc build
Revision 1.49 2003/10/08 21:15:27 olle Revision 1.49 2003/10/08 21:15:27 olle

View File

@ -75,7 +75,10 @@ unit cpupi;
ofs:=align(maxpushedparasize+LinkageAreaSizeSYSV,16); ofs:=align(maxpushedparasize+LinkageAreaSizeSYSV,16);
end; end;
tg.setfirsttemp(ofs); tg.setfirsttemp(ofs);
end; end
else
{ at 0(r1), the previous value of r1 will be stored }
tg.setfirsttemp(4);
end; end;
@ -124,7 +127,12 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.29 2003-10-01 20:34:49 peter Revision 1.30 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.29 2003/10/01 20:34:49 peter
* procinfo unit contains tprocinfo * procinfo unit contains tprocinfo
* cginfo renamed to cgbase * cginfo renamed to cgbase
* moved cgmessage to verbose * moved cgmessage to verbose

View File

@ -271,13 +271,21 @@ implementation
href : treference; href : treference;
resflags : tresflags; resflags : tresflags;
opsize : tcgsize; opsize : tcgsize;
hlabel, oldtruelabel, oldfalselabel : tasmlabel;
begin begin
oldtruelabel:=truelabel;
oldfalselabel:=falselabel;
objectlibrary.getlabel(truelabel);
objectlibrary.getlabel(falselabel);
secondpass(left);
if codegenerror then
exit;
(* (*
!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!
Causes problems with "boolvar := boolean(bytevar)" on the ppc Causes problems with "boolvar := boolean(bytevar)" on the ppc
(the conversion isn't done in that case), don't know why it works (the conversion isn't done in that case), don't know why it works
on the 80x86 (JM) on the 80x86 (JM)
*)
{ byte(boolean) or word(wordbool) or longint(longbool) must } { byte(boolean) or word(wordbool) or longint(longbool) must }
{ be accepted for var parameters } { be accepted for var parameters }
if (nf_explicit in flags) and if (nf_explicit in flags) and
@ -287,9 +295,9 @@ implementation
location_copy(location,left.location); location_copy(location,left.location);
exit; exit;
end; end;
*)
{ Already done in tppctypeconvnode.pass_2! (JM) { Already done in tppctypeconvnode.pass_2! (JM) }
secondpass(left); } secondpass(left);
if codegenerror then if codegenerror then
exit; exit;
location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def)); location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def));
@ -341,10 +349,24 @@ implementation
resflags:=left.location.resflags; resflags:=left.location.resflags;
cg.g_flags2reg(exprasmlist,location.size,resflags,hreg1); cg.g_flags2reg(exprasmlist,location.size,resflags,hreg1);
end; end;
LOC_JUMP :
begin
hreg1:=cg.getintregister(exprasmlist,OS_INT);
objectlibrary.getlabel(hlabel);
cg.a_label(exprasmlist,truelabel);
cg.a_load_const_reg(exprasmlist,OS_INT,1,hreg1);
cg.a_jmp_always(exprasmlist,hlabel);
cg.a_label(exprasmlist,falselabel);
cg.a_load_const_reg(exprasmlist,OS_INT,0,hreg1);
cg.a_label(exprasmlist,hlabel);
cg.ungetregister(exprasmlist,hreg1);
end;
else else
internalerror(10062); internalerror(10062);
end; end;
location.register := hreg1; location.register := hreg1;
truelabel:=oldtruelabel;
falselabel:=oldfalselabel;
end; end;
@ -374,7 +396,12 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.45 2003-11-04 22:30:15 florian Revision 1.46 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.45 2003/11/04 22:30:15 florian
+ type cast variant<->enum + type cast variant<->enum
* cnv. node second pass uses now as well helper wrappers * cnv. node second pass uses now as well helper wrappers

View File

@ -97,7 +97,8 @@ Unit rappcgas;
{ check for ...@ } { check for ...@ }
if actasmtoken=AS_AT then if actasmtoken=AS_AT then
begin begin
if oper.opr.ref.symbol=nil then if (oper.opr.ref.symbol=nil) and
(oper.opr.ref.offset = 0) then
Message(asmr_e_invalid_reference_syntax); Message(asmr_e_invalid_reference_syntax);
Consume(AS_AT); Consume(AS_AT);
if actasmtoken=AS_ID then if actasmtoken=AS_ID then
@ -155,7 +156,9 @@ Unit rappcgas;
Else Else
Begin Begin
oper.opr.Ref.Offset:=BuildConstExpression(false,true); oper.opr.Ref.Offset:=BuildConstExpression(false,true);
Consume_RParen; Consume(AS_RPAREN);
if actasmtoken=AS_AT then
ReadAt(oper);
end; end;
exit; exit;
End; End;
@ -175,7 +178,8 @@ Unit rappcgas;
end; end;
{ (reg,reg .. } { (reg,reg .. }
Consume(AS_COMMA); Consume(AS_COMMA);
if actasmtoken=AS_REGISTER then if (actasmtoken=AS_REGISTER) and
(oper.opr.Ref.Offset = 0) then
Begin Begin
oper.opr.ref.index:=actasmregister; oper.opr.ref.index:=actasmregister;
Consume(AS_REGISTER); Consume(AS_REGISTER);
@ -644,6 +648,11 @@ Unit rappcgas;
begin begin
dec(ord(hs[0])); dec(ord(hs[0]));
actcondition.dirhint:=DH_Minus; actcondition.dirhint:=DH_Minus;
end
else if hs[length(s)]='+' then
begin
dec(ord(hs[0]));
actcondition.dirhint:=DH_Plus;
end; end;
str2opentry:=tstr2opentry(iasmops.search(hs)); str2opentry:=tstr2opentry(iasmops.search(hs));
if assigned(str2opentry) then if assigned(str2opentry) then
@ -751,7 +760,12 @@ initialization
end. end.
{ {
$Log$ $Log$
Revision 1.6 2003-11-23 20:00:39 jonas Revision 1.7 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.6 2003/11/23 20:00:39 jonas
* fixed is_condreg * fixed is_condreg
* fixed branch condition parsing in assembler reader * fixed branch condition parsing in assembler reader

View File

@ -260,20 +260,17 @@ unit raatt;
exit; exit;
end; end;
{$ifdef POWERPC} {$ifdef POWERPC}
{ some PowerPC instructions can have the prefix - or . { some PowerPC instructions can have the postfix -, + or .
this code could be moved to is_asmopcode but I think this code could be moved to is_asmopcode but I think
it's better to ifdef it here (FK) it's better to ifdef it here (FK)
} }
if c='.' then case c of
begin '.', '-', '+':
actasmpattern:=actasmpattern+'.'; begin
c:=current_scanner.asmgetchar; actasmpattern:=actasmpattern+c;
end c:=current_scanner.asmgetchar;
else if c='-' then end
begin end;
actasmpattern:=actasmpattern+'-';
c:=current_scanner.asmgetchar;
end;
{$endif POWERPC} {$endif POWERPC}
{ Opcode ? } { Opcode ? }
If is_asmopcode(upper(actasmpattern)) then If is_asmopcode(upper(actasmpattern)) then
@ -1458,7 +1455,12 @@ end.
{ {
$Log$ $Log$
Revision 1.3 2003-11-17 23:23:47 florian Revision 1.4 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.3 2003/11/17 23:23:47 florian
+ first part of arm assembler reader + first part of arm assembler reader
Revision 1.2 2003/11/15 19:00:10 florian Revision 1.2 2003/11/15 19:00:10 florian

View File

@ -35,8 +35,8 @@ asm
{ dest in the copy loop } { dest in the copy loop }
subi r9,r3,1 subi r9,r3,1
subi r4,r4,1 subi r4,r4,1
beq LStrCopyAligned beq .LStrCopyAligned
LStrCopyAlignLoop: .LStrCopyAlignLoop:
{ load next byte } { load next byte }
lbzu r0,1(r4) lbzu r0,1(r4)
{ end of string? } { end of string? }
@ -44,9 +44,9 @@ LStrCopyAlignLoop:
{ store byte } { store byte }
stbu r0,1(r9) stbu r0,1(r9)
{ loop if misaligned bytes left and not end of string found } { loop if misaligned bytes left and not end of string found }
bdnzf eq,LStrCopyAlignLoop bdnzf cr0*4+eq,.LStrCopyAlignLoop
beq LStrCopyDone beq .LStrCopyDone
LStrCopyAligned: .LStrCopyAligned:
subi r4,r4,3 subi r4,r4,3
subi r9,r9,3 subi r9,r9,3
{ setup magic constants } { setup magic constants }
@ -66,30 +66,30 @@ LStrCopyAligned:
{ load first 4 bytes } { load first 4 bytes }
lwzu r0,4(r4) lwzu r0,4(r4)
LStrCopyAlignedLoop: .LStrCopyAlignedLoop:
{ test for zero byte } { test for zero byte }
add r10,r0,r8 add r10,r0,r8
andc r10,r10,r0 andc r10,r10,r0
and. r10,r10,r7 and. r10,r10,r7
bne LStrCopyEndFound bne .LStrCopyEndFound
stwu r0,4(r9) stwu r0,4(r9)
{ load next 4 bytes (do it here so the load can begin while the } { load next 4 bytes (do it here so the load can begin while the }
{ the branch is processed) } { the branch is processed) }
lwzu r0,4(r4) lwzu r0,4(r4)
b LStrCopyAlignedLoop b .LStrCopyAlignedLoop
LStrCopyEndFound: .LStrCopyEndFound:
{ adjust for possible $01 bytes coming before the terminating 0 byte } { adjust for possible $01 bytes coming before the terminating 0 byte }
rlwinm r8,r0,7,0,31 rlwinm r8,r0,7,0,31
andc r10,r10,r8 andc r10,r10,r8
{ result is either 0, 8, 16 or 24 depending on which byte is zero } { result is either 0, 8, 16 or 24 depending on which byte is zero }
cntlzw r10,r10 cntlzw r10,r10
addi r9,r9,3 addi r9,r9,3
LStrCopyWrapUpLoop: .LStrCopyWrapUpLoop:
subic. r10,r10,8 subic. r10,r10,8
rlwinm r0,r0,8,0,31 rlwinm r0,r0,8,0,31
stbu r0,1(r9) stbu r0,1(r9)
bge LStrCopyWrapUpLoop bge .LStrCopyWrapUpLoop
LStrCopyDone: .LStrCopyDone:
{ r3 still contains dest here } { r3 still contains dest here }
end; end;
@ -107,8 +107,8 @@ asm
mtctr r10 mtctr r10
subi r3,r3,1 subi r3,r3,1
subi r4,r4,1 subi r4,r4,1
beq LStrECopyAligned beq .LStrECopyAligned
LStrECopyAlignLoop: .LStrECopyAlignLoop:
{ load next byte } { load next byte }
lbzu r0,1(r4) lbzu r0,1(r4)
{ end of string? } { end of string? }
@ -116,9 +116,9 @@ LStrECopyAlignLoop:
{ store byte } { store byte }
stbu r0,1(r3) stbu r0,1(r3)
{ loop if misaligned bytes left and not end of string found } { loop if misaligned bytes left and not end of string found }
bdnzf eq,LStrECopyAlignLoop bdnzf cr0*4+eq,.LStrECopyAlignLoop
beq LStrECopyDone beq .LStrECopyDone
LStrECopyAligned: .LStrECopyAligned:
subi r4,r4,3 subi r4,r4,3
subi r3,r3,3 subi r3,r3,3
{ setup magic constants } { setup magic constants }
@ -141,7 +141,7 @@ LStrECopyAligned:
li r9,-32640 { 0x08080 } li r9,-32640 { 0x08080 }
andis. r9,r9,0x08080 andis. r9,r9,0x08080
} }
LStrECopyAlignedLoop: .LStrECopyAlignedLoop:
{ load next 4 bytes } { load next 4 bytes }
lwzu r0,4(r4) lwzu r0,4(r4)
@ -150,22 +150,22 @@ LStrECopyAlignedLoop:
add r10,r0,r8 add r10,r0,r8
andc r10,r10,r0 andc r10,r10,r0
and. r10,r10,r7 and. r10,r10,r7
bne LStrECopyEndFound bne .LStrECopyEndFound
stwu r0,4(r3) stwu r0,4(r3)
b LStrECopyAlignedLoop b .LStrECopyAlignedLoop
LStrECopyEndFound: .LStrECopyEndFound:
{ adjust for possible $01 bytes coming before the terminating 0 byte } { adjust for possible $01 bytes coming before the terminating 0 byte }
rlwinm r8,r0,7,0,31 rlwinm r8,r0,7,0,31
andc r10,r10,r8 andc r10,r10,r8
{ result is either 0, 8, 16 or 24 depending on which byte is zero } { result is either 0, 8, 16 or 24 depending on which byte is zero }
cntlzw r10,r10 cntlzw r10,r10
addi r3,r3,3 addi r3,r3,3
LStrECopyWrapUpLoop: .LStrECopyWrapUpLoop:
subic. r10,r10,8 subic. r10,r10,8
rlwinm r0,r0,8,0,31 rlwinm r0,r0,8,0,31
stbu r0,1(r3) stbu r0,1(r3)
bge LStrECopyWrapUpLoop bge .LStrECopyWrapUpLoop
LStrECopyDone: .LStrECopyDone:
{ r3 contains new dest here } { r3 contains new dest here }
end; end;
@ -180,17 +180,17 @@ asm
mtctr r5 mtctr r5
subi r4,r4,1 subi r4,r4,1
subi r10,r3,1 subi r10,r3,1
LStrlCopyLoop: .LStrlCopyLoop:
lbzu r0,1(r4) lbzu r0,1(r4)
cmplwi r0,0 cmplwi r0,0
stbu r0,1(r10) stbu r0,1(r10)
bdnzf cr0*4+eq, LStrlCopyLoop bdnzf cr0*4+eq, .LStrlCopyLoop
{ if we stopped because we copied a #0, we're done } { if we stopped because we copied a #0, we're done }
beq LStrlCopyDone beq .LStrlCopyDone
{ otherwise add the #0 } { otherwise add the #0 }
li r0,0 li r0,0
stb r0,1(r10) stb r0,1(r10)
LStrlCopyDone: .LStrlCopyDone:
end; end;
@ -208,13 +208,13 @@ asm
{ empty/invalid string? } { empty/invalid string? }
cmplwi r3,0 cmplwi r3,0
{ if yes, do nothing } { if yes, do nothing }
beq LStrEndDone beq .LStrEndDone
subi r3,r3,1 subi r3,r3,1
LStrEndLoop: .LStrEndLoop:
lbzu r0,1(r3) lbzu r0,1(r3)
cmplwi r0,0 cmplwi r0,0
bne LStrEndLoop bne .LStrEndLoop
LStrEndDone: .LStrEndDone:
end; end;
@ -227,7 +227,7 @@ asm
{ use r0 instead of r3 for str1 since r3 contains result } { use r0 instead of r3 for str1 since r3 contains result }
subi r9,r3,1 subi r9,r3,1
subi r4,r4,1 subi r4,r4,1
LStrCompLoop: .LStrCompLoop:
{ load next chars } { load next chars }
lbzu r0,1(r9) lbzu r0,1(r9)
{ check if one is zero } { check if one is zero }
@ -236,12 +236,12 @@ LStrCompLoop:
{ calculate difference } { calculate difference }
sub. r3,r0,r10 sub. r3,r0,r10
{ if chars not equal, we're ready } { if chars not equal, we're ready }
bne LStrCompDone bne .LStrCompDone
{ if they are equal and one is zero, then the other one is zero too } { if they are equal and one is zero, then the other one is zero too }
{ and we're done as well (r3 also contains 0 then) } { and we're done as well (r3 also contains 0 then) }
{ otherwise loop } { otherwise loop }
bne cr1,LStrCompLoop bne cr1,.LStrCompLoop
LStrCompDone: .LStrCompDone:
end; end;
@ -258,10 +258,10 @@ asm
cmplwi r5,0 cmplwi r5,0
subi r9,r3,1 subi r9,r3,1
li r3,0 li r3,0
beq LStrlCompDone beq .LStrlCompDone
mtctr r5 mtctr r5
subi r4,r4,1 subi r4,r4,1
LStrlCompLoop: .LStrlCompLoop:
{ load next chars } { load next chars }
lbzu r0,1(r9) lbzu r0,1(r9)
{ check if one is zero } { check if one is zero }
@ -270,12 +270,12 @@ LStrlCompLoop:
{ calculate difference } { calculate difference }
sub. r3,r0,r10 sub. r3,r0,r10
{ if chars not equal, we're ready } { if chars not equal, we're ready }
bne LStrlCompDone bne .LStrlCompDone
{ if they are equal and one is zero, then the other one is zero too } { if they are equal and one is zero, then the other one is zero too }
{ and we're done as well (r3 also contains 0 then) } { and we're done as well (r3 also contains 0 then) }
{ otherwise loop (if ctr <> 0) } { otherwise loop (if ctr <> 0) }
bdnzf cr1*4+eq,LStrlCompLoop bdnzf cr1*4+eq,.LStrlCompLoop
LStrlCompDone: .LStrlCompDone:
end; end;
@ -287,7 +287,7 @@ asm
{ use r28 instead of r3 for str1 since r3 contains result } { use r28 instead of r3 for str1 since r3 contains result }
subi r28,r3,1 subi r28,r3,1
subi r4,r4,1 subi r4,r4,1
LStriCompLoop: .LStriCompLoop:
{ load next chars } { load next chars }
lbzu r29,1(r28) lbzu r29,1(r28)
{ check if one is zero } { check if one is zero }
@ -296,28 +296,28 @@ LStriCompLoop:
{ calculate difference } { calculate difference }
sub. r3,r29,r30 sub. r3,r29,r30
{ if chars are equal, no further test is necessary } { if chars are equal, no further test is necessary }
beq+ LStriCompEqual beq+ .LStriCompEqual
{ make both lowercase, no branches } { make both lowercase, no branches }
li r27,0 li r27,0
li r25,0 li r25,0
{ r3 := r29 - 'A' } { r3 := r29 - 'A' }
subic r3,r29,'A' subic r3,r29,65
{ if r29 < 'A' then r27 := 0 else r27 := $ffffffff } { if r29 < 'A' then r27 := 0 else r27 := $ffffffff }
addme r27,r27 addme r27,r27
{ same for r30 } { same for r30 }
subic r3,r30,'A' subic r3,r30,65
addme r25,r25 addme r25,r25
{ r3 := 'Z' - r29 } { r3 := 'Z' - r29 }
subfic r3,r29,'Z' subfic r3,r29,90
{ if r29 < 'A' then r27 := 0 else r27 := $20 } { if r29 < 'A' then r27 := 0 else r27 := $20 }
andi. r27,r27,0x020 andi. r27,r27,0x020
{ if r29 > Z then r26 := 0 else r26 := $ffffffff } { if r29 > Z then r26 := 0 else r26 := $ffffffff }
subfe r26,r26,r26 subfe r26,r26,r26
{ same for r30 } { same for r30 }
subfic r3,r30,'Z' subfic r3,r30,90
andi. r25,r25,0x020 andi. r25,r25,0x020
subfe r24,r24,r24 subfe r24,r24,r24
@ -333,13 +333,13 @@ LStriCompLoop:
{ compare again } { compare again }
sub. r3,r29,r30 sub. r3,r29,r30
bne LStriCompDone bne .LStriCompDone
LStriCompEqual: .LStriCompEqual:
{ if they are equal and one is zero, then the other one is zero too } { if they are equal and one is zero, then the other one is zero too }
{ and we're done as well (r3 also contains 0 then) } { and we're done as well (r3 also contains 0 then) }
{ otherwise loop } { otherwise loop }
bne cr1,LStriCompLoop bne cr1,.LStriCompLoop
LStriCompDone: .LStriCompDone:
end; end;
@ -355,10 +355,10 @@ asm
cmplwi r5,0 cmplwi r5,0
subi r9,r3,1 subi r9,r3,1
li r3,0 li r3,0
beq- LStrliCompDone beq- .LStrliCompDone
mtctr r5 mtctr r5
subi r4,r4,1 subi r4,r4,1
LStrliCompLoop: .LStrliCompLoop:
{ load next chars } { load next chars }
lbzu r0,1(r9) lbzu r0,1(r9)
{ check if one is zero } { check if one is zero }
@ -367,21 +367,21 @@ LStrliCompLoop:
{ calculate difference } { calculate difference }
sub. r3,r0,r10 sub. r3,r0,r10
{ if chars are equal, no further test is necessary } { if chars are equal, no further test is necessary }
beq LStrliCompEqual beq .LStrliCompEqual
{ see stricomp for explanation } { see stricomp for explanation }
li r8,0 li r8,0
li r5,0 li r5,0
subic r3,r0,'A' subic r3,r0,65
addme r8,r8 addme r8,r8
subic r3,r10,'A' subic r3,r10,65
addme r5,r5 addme r5,r5
subfic r3,r0,'Z' subfic r3,r0,90
andi. r8,r8,0x020 andi. r8,r8,0x020
subfe r7,r7,r7 subfe r7,r7,r7
subfic r3,r10,'Z' subfic r3,r10,90
andi. r5,r5,0x020 andi. r5,r5,0x020
subfe r24,r24,r24 subfe r24,r24,r24
@ -392,13 +392,13 @@ LStrliCompLoop:
{ compare again } { compare again }
sub. r3,r0,r10 sub. r3,r0,r10
bne LStrliCompDone bne .LStrliCompDone
LStrliCompEqual: .LStrliCompEqual:
{ if they are equal and one is zero, then the other one is zero too } { if they are equal and one is zero, then the other one is zero too }
{ and we're done as well (r3 also contains 0 then) } { and we're done as well (r3 also contains 0 then) }
{ otherwise loop (if ctr <> 0) } { otherwise loop (if ctr <> 0) }
bdnzf cr1*4+eq,LStrliCompLoop bdnzf cr1*4+eq,.LStrliCompLoop
LStrliCompDone: .LStrliCompDone:
end; end;
@ -408,16 +408,16 @@ asm
{ empty/invalid string? } { empty/invalid string? }
cmplwi r3,0 cmplwi r3,0
{ if yes, do nothing } { if yes, do nothing }
beq LStrScanDone beq .LStrScanDone
subi r3,r3,1 subi r3,r3,1
LStrScanLoop: .LStrScanLoop:
lbzu r0,1(r3) lbzu r0,1(r3)
cmplwi r0,0 cmplwi r0,0
cmplw cr1,r0,r4 cmplw cr1,r0,r4
bne LStrScanLoop bne .LStrScanLoop
beq cr1,LStrScanDone beq cr1,.LStrScanDone
li r3, 0 li r3, 0
LStrScanDone: .LStrScanDone:
end; end;
@ -427,21 +427,21 @@ asm
{ empty/invalid string? } { empty/invalid string? }
cmplwi r3,0 cmplwi r3,0
{ if yes, do nothing } { if yes, do nothing }
beq LStrrScanDone beq .LStrrScanDone
{ make r5 will be walking through the string } { make r5 will be walking through the string }
subi r5,r3,1 subi r5,r3,1
{ assume not found } { assume not found }
li r3,0 li r3,0
LStrrScanLoop: .LStrrScanLoop:
lbzu r10,1(r5) lbzu r10,1(r5)
cmplw cr1,r10,r4 cmplw cr1,r10,r4
cmplwi cr0,r10,0 cmplwi cr0,r10,0
bne+ cr1,LStrrScanNotFound bne+ cr1,.LStrrScanNotFound
{ store address of found position } { store address of found position }
mr r3,r5 mr r3,r5
LStrrScanNotFound: .LStrrScanNotFound:
bne LStrrScanLoop bne .LStrrScanLoop
LStrrScanDone: .LStrrScanDone:
end; end;
@ -449,20 +449,20 @@ end;
function strupper(p : pchar) : pchar;assembler; function strupper(p : pchar) : pchar;assembler;
asm asm
cmplwi r3,0 cmplwi r3,0
beq LStrUpperNil beq .LStrUpperNil
subi r9,r3,1 subi r9,r3,1
LStrUpperLoop: .LStrUpperLoop:
lbzu r10,1(r9) lbzu r10,1(r9)
{ a <= x <= b <=> cardinal(x-a) <= cardinal(b-a) } { a <= x <= b <=> cardinal(x-a) <= cardinal(b-a) }
subi r0,r10,97 subi r0,r10,97
cmplwi r0,122-97 cmplwi r0,122-97
cmplwi cr1,r10,0 cmplwi cr1,r10,0
subi r10,r10,0x20 subi r10,r10,0x20
bgt LStrUpper1 bgt .LStrUpper1
stb r10,0(r9) stb r10,0(r9)
LStrUpper1: .LStrUpper1:
bne cr1,LStrUpperLoop bne cr1,.LStrUpperLoop
LStrUpperNil: .LStrUpperNil:
end; end;
@ -470,26 +470,31 @@ end;
function strlower(p : pchar) : pchar;assembler; function strlower(p : pchar) : pchar;assembler;
asm asm
cmplwi r3,0 cmplwi r3,0
beq LStrLowerNil beq .LStrLowerNil
subi r9,r3,1 subi r9,r3,1
LStrLowerLoop: .LStrLowerLoop:
lbzu r10,1(r9) lbzu r10,1(r9)
{ a <= x <= b <=> cardinal(x-a) <= cardinal(b-a) } { a <= x <= b <=> cardinal(x-a) <= cardinal(b-a) }
subi r0,r10,65 subi r0,r10,65
cmplwi r0,90-65 cmplwi r0,90-65
cmplwi cr1,r10,0 cmplwi cr1,r10,0
addi r10,r10,0x20 addi r10,r10,0x20
bgt LStrLower1 bgt .LStrLower1
stb r10,0(r9) stb r10,0(r9)
LStrLower1: .LStrLower1:
bne cr1,LStrLowerLoop bne cr1,.LStrLowerLoop
LStrLowerNil: .LStrLowerNil:
end; end;
{ {
$Log$ $Log$
Revision 1.21 2003-08-24 20:51:27 olle Revision 1.22 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.21 2003/08/24 20:51:27 olle
+ added MacOS compatible constant loading + added MacOS compatible constant loading
Revision 1.20 2003/07/07 20:23:46 peter Revision 1.20 2003/07/07 20:23:46 peter

View File

@ -29,21 +29,26 @@ asm
cmplwi r0,0 cmplwi r0,0
mtctr r0 mtctr r0
subi r10,r3,1 subi r10,r3,1
beq LStrPCopyEmpty beq .LStrPCopyEmpty
LStrPCopyLoop: .LStrPCopyLoop:
{ copy everything } { copy everything }
lbzu r0,1(r4) lbzu r0,1(r4)
stbu r0,1(r10) stbu r0,1(r10)
bdnz LStrPCopyLoop bdnz .LStrPCopyLoop
{ add terminating #0 } { add terminating #0 }
li r0,0 li r0,0
LStrPCopyEmpty: .LStrPCopyEmpty:
stb r0,1(r10) stb r0,1(r10)
end; end;
{ {
$Log$ $Log$
Revision 1.10 2003-07-07 20:23:46 peter Revision 1.11 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.10 2003/07/07 20:23:46 peter
* added defines to override generic implementations * added defines to override generic implementations
Revision 1.9 2003/06/14 12:41:09 jonas Revision 1.9 2003/06/14 12:41:09 jonas

View File

@ -23,11 +23,11 @@ function InterLockedDecrement (var Target: integer) : Integer; assembler;
{ output: target-1 in r3 } { output: target-1 in r3 }
{ side-effect: target := target-1 } { side-effect: target := target-1 }
asm asm
InterLockedDecLoop: .LInterLockedDecLoop:
lwarx r10,r10,r3 lwarx r10,r10,r3
subi r10,r10,1 subi r10,r10,1
stwcx. r10,r10,r3 stwcx. r10,r10,r3
bne InterLockedDecLoop bne .LInterLockedDecLoop
mr r3,r10 mr r3,r10
end; end;
@ -37,11 +37,11 @@ function InterLockedIncrement (var Target: integer) : Integer; assembler;
{ output: target+1 in r3 } { output: target+1 in r3 }
{ side-effect: target := target+1 } { side-effect: target := target+1 }
asm asm
InterLockedIncLoop: .LInterLockedIncLoop:
lwarx r10,r10,r3 lwarx r10,r10,r3
addi r10,r10,1 addi r10,r10,1
stwcx. r10,r10,r3 stwcx. r10,r10,r3
bne InterLockedIncLoop bne .LInterLockedIncLoop
mr r3,r10 mr r3,r10
end; end;
@ -51,10 +51,10 @@ function InterLockedExchange (var Target: integer;Source : integer) : Integer; a
{ output: target in r3 } { output: target in r3 }
{ side-effect: target := source } { side-effect: target := source }
asm asm
InterLockedXchgLoop: .LInterLockedXchgLoop:
lwarx r10,r10,r3 lwarx r10,r10,r3
stwcx. r4,r10,r3 stwcx. r4,r10,r3
bne InterLockedXchgLoop bne .LInterLockedXchgLoop
mr r3,r10 mr r3,r10
end; end;
@ -64,18 +64,23 @@ function InterLockedExchangeAdd (var Target: integer;Source : integer) : Integer
{ output: target in r3 } { output: target in r3 }
{ side-effect: target := target+source } { side-effect: target := target+source }
asm asm
InterLockedXchgAddLoop: .LInterLockedXchgAddLoop:
lwarx r10,r10,r3 lwarx r10,r10,r3
add r10,r10,r4 add r10,r10,r4
stwcx. r10,r10,r3 stwcx. r10,r10,r3
bne InterLockedXchgAddLoop bne .LInterLockedXchgAddLoop
sub r3,r10,r4 sub r3,r10,r4
end; end;
{ {
$Log$ $Log$
Revision 1.4 2003-08-24 20:50:11 olle Revision 1.5 2003-11-29 16:27:19 jonas
* fixed several ppc assembler reader related problems
* local vars in assembler procedures now start at offset 4
* fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
Revision 1.4 2003/08/24 20:50:11 olle
* changed used scratchreg from r0 to r10 * changed used scratchreg from r0 to r10
Revision 1.3 2003/04/24 12:13:23 florian Revision 1.3 2003/04/24 12:13:23 florian