Attaching source & assembler
function TBarbarina.DoAttack(uix, AttackLoc: integer): boolean; // AttackLoc=maNextCity means bombard only
var MoveResult, Kind, Temp, MoveStyle, TestLoc, TestTime, NextLoc, NextTime, V8, RecoverTurns, ecix: integer; NextTile: cardinal; AttackPositionReached, IsBombardment: boolean; Adjacent: TVicinity8Loc; PreLoc : tPreLoc; Reached : array[0..lxmax * lymax - 1] of boolean; begin PreLoc := default (tPreLoc); Result := False; IsBombardment := AttackLoc = maNextCity; with MyUnit[uix] do begin if (MyModel[mix].Domain = dGround) and (MyModel[mix].Attack > 0) then if MyModel[mix].Speed >= 250 then Kind := ukFast else Kind := ukSlow else Kind := 0; fillchar(Reached, MapSize, False); AttackPositionReached := False; MoveStyle := GetMyMoveStyle(mix, Health); Pile.Create(MapSize); Pile.Put(Loc, $800 - Movement); while Pile.Get(TestLoc, TestTime) do begin if (TestTime >= $800) or (AttackLoc = maNextCity) and (TestTime > $800 - 100) then break; Reached[TestLoc] := True; V8_to_Loc(TestLoc, Adjacent); for V8 := 0 to 7 do begin NextLoc := Adjacent[V8]; if NextLoc >= 0 then begin if IsBombardment and (Map[NextLoc] and (fCity or fUnit or fOwned or fObserved) = fCity or fObserved) and (RO.Treaty[RO.Territory[NextLoc]] < trPeace) then begin City_FindEnemyCity(NextLoc, ecix); assert(ecix >= 0); with RO.EnemyCity[ecix] do if (Size > 2) and (Flags and ciCoastalFort = 0) then AttackLoc := NextLoc; end; if (NextLoc = AttackLoc) and ((MyModel[mix].Domain <> dSea) or (Map[TestLoc] and fTerrain < fGrass)) then // ships can only attack from water begin AttackPositionReached := True; break; end else if not Reached[NextLoc] then begin NextTile := Map[NextLoc]; if (NextTile and (fUnit or fCity) = 0) or (NextTile and fOwned <> 0) then case CheckStep(MoveStyle, TestTime, V8 and 1, NextTime, RecoverTurns, Map[TestLoc], NextTile, True) of csOk: if Pile.Put(NextLoc, NextTime) then PreLoc[NextLoc] := TestLoc; csForbiddenTile: Reached[NextLoc] := True; // don't check moving there again csCheckTerritory: if RO.Territory[NextLoc] = RO.Territory[TestLoc] then if Pile.Put(NextLoc, NextTime) then PreLoc[NextLoc] := TestLoc; end; end; end; end; if AttackPositionReached then begin PreLoc[NextLoc] := TestLoc; break; end; end; Pile.Free; if not AttackPositionReached then exit; TestLoc := AttackLoc; // if AttackLoc <> TestLoc then // halt; NextLoc := PreLoc[TestLoc]; while TestLoc <> Loc do begin Temp := TestLoc; TestLoc := NextLoc; NextLoc := PreLoc[TestLoc]; PreLoc[TestLoc] := Temp; end; UnitPresence[Loc] := UnitPresence[Loc] and not Kind; // assume unit was only one of kind here repeat NextLoc := PreLoc[Loc]; MoveResult := Unit_Step(uix, NextLoc); until (NextLoc = AttackLoc) or (MoveResult and rExecuted = 0) or (MoveResult and rUnitRemoved <> 0); Result := (NextLoc = AttackLoc) and (MoveResult and rExecuted <> 0); if IsBombardment and Result then begin City_FindEnemyCity(AttackLoc, ecix); assert(ecix >= 0); while (Movement >= 100) and (RO.EnemyCity[ecix].Size > 2) do Unit_Step(uix, AttackLoc); end; if Loc >= 0 then UnitPresence[Loc] := UnitPresence[Loc] or Kind; end; end;
.section .text.n_barbarina$_$tbarbarina_$__$$_doattack$longint$longint$$boolean .balign 16,0x90 .globl BARBARINA$_$TBARBARINA_$__$$_DOATTACK$LONGINT$LONGINT$$BOOLEAN .type BARBARINA$_$TBARBARINA_$__$$_DOATTACK$LONGINT$LONGINT$$BOOLEAN,@function BARBARINA$_$TBARBARINA_$__$$_DOATTACK$LONGINT$LONGINT$$BOOLEAN: .Lc25: # Temps allocated between rsp+83236 and rsp+83296 # [511] begin pushq %rbx pushq %r12 pushq %r13 pushq %r14 pushq %r15 leaq -83296(%rsp),%rsp .Lc27: # Var $result located in register al # Var MoveResult located in register ebx # Var Kind located in register eax # Var Temp located in register ecx # Var MoveStyle located in register eax # Var TestLoc located at rsp+24, size=OS_S32 # Var TestTime located at rsp+28, size=OS_S32 # Var NextLoc located in register ebx # Var NextTime located at rsp+32, size=OS_S32 # Var V8 located in register r12d # Var RecoverTurns located at rsp+36, size=OS_S32 # Var ecix located at rsp+40, size=OS_S32 # Var NextTile located in register r13d # Var AttackPositionReached located in register al # Var IsBombardment located in register al # Var Adjacent located at rsp+44, size=OS_NO # Var PreLoc located at rsp+76, size=OS_NO # Var Reached located at rsp+33340, size=OS_NO # Var $_zero_$BARBARINA_$$_TPRELOC located at rsp+49972, size=OS_NO movq %rdi,%r12 # Var $self located in register r12 movl %esi,%eax movq %rax,83248(%rsp) # Var uix located in register eax movl %edx,%eax movq %rax,83288(%rsp) # Var AttackLoc located in register eax # [503] var leaq 49972(%rsp),%rdi xorl %edx,%edx movl $33264,%esi call SYSTEM_$$_FILLCHAR$formal$INT64$BYTE@PLT # [512] PreLoc := default (tPreLoc); leaq 76(%rsp),%rdi leaq 49972(%rsp),%rsi movl $4158,%ecx rep movsq # Var $result located in register al # [513] Result := False; movb $0,83240(%rsp) # [514] IsBombardment := AttackLoc = maNextCity; movl 83288(%rsp),%eax cmpl $-1,%eax # Var IsBombardment located in register al seteb 83264(%rsp) # [515] with MyUnit[uix] do movq 32(%r12),%rcx movl 83248(%rsp),%edx shlq $5,%rdx leaq (%rcx,%rdx),%rbx # [517] if (MyModel[mix].Domain = dGround) and (MyModel[mix].Attack > 0) then movq 48(%r12),%rdx movzwl 14(%rbx),%eax imulq $68,%rax,%rax addq %rdx,%rax cmpb $0,17(%rax) jne .Lj273 cmpw $0,18(%rax) jna .Lj273 # [518] if MyModel[mix].Speed >= 250 then movq 48(%r12),%rdx movzwl 14(%rbx),%eax imulq $68,%rax,%rax cmpw $250,22(%rdx,%rax) jnae .Lj276 # [519] Kind := ukFast movl $2,%eax movq %rax,83256(%rsp) jmp .Lj278 .Lj276: # [521] Kind := ukSlow movl $1,%eax movq %rax,83256(%rsp) jmp .Lj278 .Lj273: # [523] Kind := 0; xorl %eax,%eax movq %rax,83256(%rsp) .Lj278: # [524] fillchar(Reached, MapSize, False); movq U_$CUSTOMAI_$$_MAPSIZE@GOTPCREL(%rip),%rax movslq (%rax),%rsi leaq 33340(%rsp),%rdi xorb %dl,%dl call SYSTEM_$$_FILLCHAR$formal$INT64$BOOLEAN@PLT # Var AttackPositionReached located in register r15b # [525] AttackPositionReached := False; xorb %r15b,%r15b # [526] MoveStyle := GetMyMoveStyle(mix, Health); movq %r12,83272(%rsp) # Var $self located in register rax movq %r12,%rdi movq %rbx,%rax # [Barbarina.pas] movsbl 22(%rax),%edx movq %rax,%rbx # [Barbarina.pas] movswl 14(%rbx),%esi call TOOLAI$_$TTOOLAI_$__$$_GETMYMOVESTYLE$LONGINT$LONGINT$$LONGINT@PLT # Var MoveStyle located in register r14d movl %eax,%r14d # [527] Pile.Create(MapSize); movq U_$CUSTOMAI_$$_MAPSIZE@GOTPCREL(%rip),%rax movl (%rax),%edi call PILE_$$_CREATE$LONGINT@PLT movq %rbx,%rdx # [Barbarina.pas] # [528] Pile.Put(Loc, $800 - Movement); movswl 20(%rdx),%eax movl $2048,%esi subl %eax,%esi movq %rdx,83280(%rsp) # [Barbarina.pas] movq %rdx,%rax movl (%rax),%edi call PILE_$$_PUT$LONGINT$LONGINT$$BOOLEAN@PLT # [529] while Pile.Get(TestLoc, TestTime) do jmp .Lj280 .balign 8,0x90 .Lj279: movl 28(%rsp),%edx # [531] if (TestTime >= $800) or (AttackLoc = maNextCity) and (TestTime > $800 - 100) then cmpl $2048,%edx jge .Lj281 movl 83288(%rsp),%eax cmpl $-1,%eax jne .Lj284 cmpl $1948,%edx jg .Lj281 .Lj284: # [533] Reached[TestLoc] := True; movl 24(%rsp),%eax movb $1,33340(%rsp,%rax,1) # [534] V8_to_Loc(TestLoc, Adjacent); leaq 44(%rsp),%rsi movl 24(%rsp),%edi call CUSTOMAI_$$_V8_TO_LOC$LONGINT$TVICINITY8LOC@PLT # [535] for V8 := 0 to 7 do movl $-1,%r12d .balign 8,0x90 .Lj288: addl $1,%r12d # [537] NextLoc := Adjacent[V8]; movl %r12d,%eax movl 44(%rsp,%rax,4),%ebx # [538] if NextLoc >= 0 then testl %ebx,%ebx jnge .Lj292 # [540] if IsBombardment and (Map[NextLoc] and (fCity or movb 83264(%rsp),%al testb %al,%al je .Lj294 movq 83272(%rsp),%rax movq 24(%rax),%rdx movl %ebx,%eax movl (%rdx,%rax,4),%eax andl $15728640,%eax cmpl $9437184,%eax jne .Lj294 # [542] (RO.Treaty[RO.Territory[NextLoc]] < trPeace) then movq 83272(%rsp),%rax movq 16(%rax),%rcx movq 24(%rcx),%rdx movl %ebx,%eax movzbl (%rdx,%rax,1),%eax cmpl $2,500(%rcx,%rax,4) jnl .Lj294 # [544] City_FindEnemyCity(NextLoc, ecix); leaq 40(%rsp),%rdx movl %ebx,%esi movq 83272(%rsp),%rdi call CUSTOMAI$_$TCUSTOMAI_$__$$_CITY_FINDENEMYCITY$LONGINT$LONGINT@PLT # [546] with RO.EnemyCity[ecix] do movq 83272(%rsp),%rax movq 16(%rax),%rdx movq 64(%rdx),%rdx movl 40(%rsp),%eax imulq $20,%rax,%rax addq %rdx,%rax # [547] if (Size > 2) and (Flags and ciCoastalFort = 0) then cmpw $2,16(%rax) jna .Lj298 movl 18(%rax),%eax andl $4,%eax jne .Lj298 # [548] AttackLoc := NextLoc; movl %ebx,%eax movq %rax,83288(%rsp) .Lj298: .Lj294: # [550] if (NextLoc = AttackLoc) and ((MyModel[mix].Domain <> dSea) or movl 83288(%rsp),%eax cmpl %ebx,%eax jne .Lj301 movq 83272(%rsp),%rax movq 48(%rax),%rcx movq 83280(%rsp),%rax movzwl 14(%rax),%edx imulq $68,%rdx,%rax cmpb $1,17(%rcx,%rax) jne .Lj302 # [551] (Map[TestLoc] and fTerrain < fGrass)) then movq 83272(%rsp),%rax movq 24(%rax),%rdx movl 24(%rsp),%eax movl (%rdx,%rax,4),%eax andl $31,%eax cmpl $2,%eax jnb .Lj301 .Lj302: # [554] AttackPositionReached := True; movb $1,%r15b # [555] break; jmp .Lj290 .Lj301: # [557] else if not Reached[NextLoc] then movl %ebx,%eax cmpb $0,33340(%rsp,%rax,1) jne .Lj308 # [559] NextTile := Map[NextLoc]; movq 83272(%rsp),%rax movq 24(%rax),%rdx movl %ebx,%eax movl (%rdx,%rax,4),%r13d # [560] if (NextTile and (fUnit or fCity) = 0) or movl %r13d,%eax andl $12582912,%eax je .Lj309 # [561] (NextTile and fOwned <> 0) then movl %r13d,%eax andl $2097152,%eax je .Lj311 .Lj309: # [562] case CheckStep(MoveStyle, TestTime, V8 and 1, NextTime, movb $1,16(%rsp) # [563] RecoverTurns, Map[TestLoc], NextTile, True) of movl %r13d,8(%rsp) movq 83272(%rsp),%rax movq 24(%rax),%rdx movl 24(%rsp),%eax movl (%rdx,%rax,4),%eax movl %eax,(%rsp) movl %r12d,%eax andl $1,%eax movl %eax,%ecx leaq 36(%rsp),%r9 leaq 32(%rsp),%r8 movl 28(%rsp),%edx movl %r14d,%esi movq 83272(%rsp),%rdi call TOOLAI$_$TTOOLAI_$__$$_CHECKSTEP$crc8012ABE0@PLT testl %eax,%eax jl .Lj313 testl %eax,%eax je .Lj314 subl $1,%eax je .Lj315 subl $2,%eax je .Lj316 jmp .Lj313 .Lj314: # [565] if Pile.Put(NextLoc, NextTime) then movl 32(%rsp),%esi movl %ebx,%edi call PILE_$$_PUT$LONGINT$LONGINT$$BOOLEAN@PLT testb %al,%al je .Lj312 # [566] PreLoc[NextLoc] := TestLoc; movl %ebx,%edx movw 24(%rsp),%ax movw %ax,76(%rsp,%rdx,2) jmp .Lj312 .Lj315: # [568] Reached[NextLoc] := True; // don't check moving there again movl %ebx,%eax movb $1,33340(%rsp,%rax,1) jmp .Lj312 .Lj316: # [570] if RO.Territory[NextLoc] = RO.Territory[TestLoc] then movq 83272(%rsp),%rax movq 16(%rax),%rdx movq 24(%rdx),%rcx movl %ebx,%eax movl 24(%rsp),%edx movb (%rcx,%rax,1),%al cmpb (%rcx,%rdx,1),%al jne .Lj312 # [571] if Pile.Put(NextLoc, NextTime) then movl 32(%rsp),%esi movl %ebx,%edi call PILE_$$_PUT$LONGINT$LONGINT$$BOOLEAN@PLT testb %al,%al je .Lj312 # [572] PreLoc[NextLoc] := TestLoc; movl %ebx,%eax movw 24(%rsp),%dx movw %dx,76(%rsp,%rax,2) .Lj313: .Lj312: .Lj311: .Lj308: .Lj292: cmpl $7,%r12d jnge .Lj288 .Lj290: # [577] if AttackPositionReached then testb %r15b,%r15b je .Lj324 # [579] PreLoc[NextLoc] := TestLoc; movl %ebx,%edx movw 24(%rsp),%ax movw %ax,76(%rsp,%rdx,2) # [580] break; jmp .Lj281 .Lj324: .Lj280: leaq 28(%rsp),%rsi leaq 24(%rsp),%rdi call PILE_$$_GET$LONGINT$LONGINT$$BOOLEAN@PLT testb %al,%al jne .Lj279 .Lj281: # [584] if not AttackPositionReached then testb %r15b,%r15b je .Lj270 # [587] TestLoc := AttackLoc; movl 83288(%rsp),%eax # Var AttackLoc located in register r13d movl %eax,24(%rsp) # [591] NextLoc := PreLoc[TestLoc]; movzwl 76(%rsp,%rax,2),%eax # Var NextLoc located in register r12d movl %eax,%r12d # [592] while TestLoc <> Loc do jmp .Lj328 .balign 8,0x90 .Lj327: # [594] Temp := TestLoc; movl 24(%rsp),%ecx # [595] TestLoc := NextLoc; movl %r12d,24(%rsp) # [596] NextLoc := PreLoc[TestLoc]; movl %r12d,%eax movzwl 76(%rsp,%rax,2),%eax movl %eax,%r12d # [597] PreLoc[TestLoc] := Temp; movl 24(%rsp),%edx movw %cx,76(%rsp,%rdx,2) .Lj328: movl 24(%rsp),%eax movq 83280(%rsp),%rdx cmpl (%rdx),%eax jne .Lj327 # [600] UnitPresence[Loc] := UnitPresence[Loc] and not Kind; movl 83256(%rsp),%ecx notl %ecx leaq U_$BARBARINA_$$_UNITPRESENCE(%rip),%rdx movq 83280(%rsp),%rax movl (%rax),%esi movl %esi,%eax movzbl (%rdx,%rax,1),%eax andl %eax,%ecx andl %esi,%esi movb %cl,(%rdx,%rsi,1) .balign 8,0x90 .Lj330: # [603] NextLoc := PreLoc[Loc]; movq 83280(%rsp),%rdx movl (%rdx),%eax movzwl 76(%rsp,%rax,2),%eax movl %eax,%r12d # [604] MoveResult := Unit_Step(uix, NextLoc); movl %r12d,%edx movl 83248(%rsp),%esi movq 83272(%rsp),%rdi call CUSTOMAI$_$TCUSTOMAI_$__$$_UNIT_STEP$LONGINT$LONGINT$$LONGINT@PLT movl %eax,%ebx # [605] until (NextLoc = AttackLoc) or (MoveResult and rExecuted = 0) or cmpl %r12d,%r13d je .Lj332 movl %ebx,%eax andl $1073741824,%eax je .Lj332 # [606] (MoveResult and rUnitRemoved <> 0); movl %ebx,%eax andl $268435456,%eax je .Lj330 .Lj332: # [607] Result := (NextLoc = AttackLoc) and (MoveResult and rExecuted <> 0); cmpl %r12d,%r13d jne .Lj338 movl %ebx,%eax andl $1073741824,%eax je .Lj338 movb $1,83240(%rsp) jmp .Lj340 .Lj338: movb $0,83240(%rsp) .Lj340: # [609] if IsBombardment and Result then movb 83240(%rsp),%al andb 83264(%rsp),%al je .Lj342 # [611] City_FindEnemyCity(AttackLoc, ecix); leaq 40(%rsp),%rdx movl %r13d,%esi movq 83272(%rsp),%rdi call CUSTOMAI$_$TCUSTOMAI_$__$$_CITY_FINDENEMYCITY$LONGINT$LONGINT@PLT # [613] while (Movement >= 100) and (RO.EnemyCity[ecix].Size > 2) do jmp .Lj344 .balign 8,0x90 .Lj343: # [614] Unit_Step(uix, AttackLoc); movl %r13d,%edx movl 83248(%rsp),%esi movq 83272(%rsp),%rdi call CUSTOMAI$_$TCUSTOMAI_$__$$_UNIT_STEP$LONGINT$LONGINT$$LONGINT@PLT .Lj344: movq 83280(%rsp),%rax cmpw $100,20(%rax) jnge .Lj345 movq 83272(%rsp),%rax movq 16(%rax),%rdx movq 64(%rdx),%rdx movl 40(%rsp),%eax imulq $20,%rax,%rax cmpw $2,16(%rdx,%rax) ja .Lj343 .Lj345: .Lj342: # [617] if Loc >= 0 then movq 83280(%rsp),%rax cmpl $0,(%rax) jnge .Lj350 leaq U_$BARBARINA_$$_UNITPRESENCE(%rip),%rcx movq 83280(%rsp),%rax movl (%rax),%esi # [618] UnitPresence[Loc] := UnitPresence[Loc] or Kind; movl %esi,%eax movzbl (%rcx,%rax,1),%edx movl 83256(%rsp),%eax orl %eax,%edx andl %esi,%esi movb %dl,(%rcx,%rsi,1) .Lj350: .Lj270: # [620] end; movb 83240(%rsp),%al leaq 83296(%rsp),%rsp popq %r15 popq %r14 popq %r13 popq %r12 popq %rbx ret .Lc26: .Le8:
_______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal