summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-04-13 19:51:04 -0700
committerCliff Click <cliffc@acm.org>2025-04-13 19:51:04 -0700
commit40a6f7b90e9e5d42bdacabb1c9e93fab5d27f63d (patch)
tree93d563ab5134dc23b2e08f712bb9f1d78501020d
parent450dd5169ebbfd8664d073b0d8baea201dae0ed2 (diff)
downloadSimple-40a6f7b90e9e5d42bdacabb1c9e93fab5d27f63d.tar.gz
Simple-40a6f7b90e9e5d42bdacabb1c9e93fab5d27f63d.zip
EvalRISC5 handles calloc
Patch calls to calloc with a sentinel; emulator spots call to sentinel and mimics calloc on the internal heap.
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java14
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java22
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java39
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java23
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java59
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java10
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/progs/jig.smp282
7 files changed, 123 insertions, 326 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
index fb46a6a2..8f0a97c8 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
@@ -343,25 +343,19 @@ public class CodeGen {
// ---------------------------
// Encoding
public int _tEncode;
- public boolean _JIT;
- public Encoding _encoding;
- public void preEncode() { } // overridden by M2
+ public Encoding _encoding; // Encoding object
+ public void preEncode() { } // overridden by alternative ports
public CodeGen encode(boolean jit) {
assert _phase == Phase.RegAlloc;
_phase = Phase.Encoding;
long t0 = System.currentTimeMillis();
_encoding = new Encoding(this);
- _JIT = jit;
preEncode();
- _encoding.encode();
+ _encoding.encode(jit);
_tEncode = (int)(System.currentTimeMillis() - t0);
return this;
}
- public CodeGen encode() {
- return encode(false);
- }
- // Encoded binary, no relocation info
- public byte[] binary() { return _encoding.bits(); }
+ public CodeGen encode() { return encode(false); }
// ---------------------------
// Exporting to external formats
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
index 48b9ea5f..74c128be 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
@@ -153,7 +153,7 @@ public class Encoding {
_bigCons.put(relo,new Relo(relo,t,(byte)off,(byte)elf));
}
- void encode() {
+ void encode(boolean jit) {
// Basic block layout: invert branches to keep blocks in-order; insert
// unconditional jumps. Attempt to keep backwards branches taken,
// forwards not-taken (this is the default prediction on most
@@ -171,6 +171,9 @@ public class Encoding {
// Patch RIP-relative and local encodings now.
patchLocalRelocations();
+ // If JIT'ing (in memory execution), patch the global relocations now
+ if( jit )
+ patchGlobalRelocations();
}
// Basic block layout: invert branches to keep blocks in-order; insert
@@ -416,9 +419,26 @@ public class Encoding {
void patchLocalRelocations() {
// Walk the local code-address relocations
for( Node src : _internals.keySet() ) {
+ int start = _opStart[src._nid];
Node dst = _internals.get(src);
int target = _opStart[dst._nid];
+ ((RIPRelSize)src).patch(this, start, _opLen[src._nid], target - start);
+ }
+ }
+
+ // A series of libc/external calls that Simple can link against in a JIT.
+ // Since no runtime in the JVM process, using magic numbers for the CPU
+ // emulators to pick up on.
+ public static int SENTINAL_CALLOC = -2;
+
+ void patchGlobalRelocations() {
+ for( Node src : _externals.keySet() ) {
int start = _opStart[src._nid];
+ String dst = _externals.get(src);
+ int target = switch( dst ) {
+ case "calloc" -> SENTINAL_CALLOC;
+ default -> throw Utils.TODO();
+ };
((RIPRelSize)src).patch(this, start, _opLen[src._nid], target - start);
}
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java
index dfa40cad..0ca76d3f 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java
@@ -5,14 +5,12 @@ import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.print.ASMPrinter;
-public class NewRISC extends NewNode implements MachNode {
+public class NewRISC extends NewNode implements MachNode, RIPRelSize {
// A pre-zeroed chunk of memory.
NewRISC( NewNode nnn ) { super(nnn); }
@Override public String op() { return "alloc"; }
- @Override public RegMask regmap(int i) {
- return i==1 ? riscv.A0_MASK : null; // Size input or mem aliases
- }
- @Override public RegMask outregmap(int i) { return i == 1 ? riscv.A0_MASK : null; }
+ @Override public RegMask regmap(int i) { return i==1 ? riscv.A1_MASK : null; }
+ @Override public RegMask outregmap(int i) { return i==1 ? riscv.A0_MASK : null; }
@Override public RegMask outregmap() { return null; }
@Override public RegMask killmap() { return riscv.riscCallerSave(); }
@@ -21,13 +19,36 @@ public class NewRISC extends NewNode implements MachNode {
enc.external(this,"calloc");
// A1 is a caller-save, allowed to crush building external address
// auipc
- enc.add4(riscv.u_type(riscv.OP_AUIPC, riscv.A1, 0));
- enc.add4(riscv.i_type(riscv.OP_JALR, riscv.RPC, 0, riscv.A1, 0));
+ enc.add4(riscv.i_type(riscv.OP_IMM , riscv.A0 , 0, riscv.ZERO, 1));
+ enc.add4(riscv.u_type(riscv.OP_AUIPC, riscv.A2 , 0));
+ enc.add4(riscv.i_type(riscv.OP_JALR , riscv.RPC, 0, riscv.A2, 0));
+ }
+
+ // Patch is for running "new" in a JIT.
+ // Delta is from opcode start
+ @Override public byte encSize(int delta) { return 4*3; }
+
+ // Patch is for running "new" in a JIT.
+ // Delta is from opcode start
+ @Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
+ // Odd-number patches are JIT emulator targets.
+ if( (delta&3)!=0 ) {
+ //enc.patch4(opStart+4, riscv.i_type(riscv.OP_IMM, riscv.ZERO , 0, riscv.ZERO, 0));
+ //enc.patch4(opStart,riscv.j_type(riscv.OP_JAL, riscv.RPC, opStart+delta));
+
+ int imm20 = delta>>12;
+ if( ((delta>>11)&1)==1 ) imm20++; // Correct accidental sign extension
+ int imm12 = delta&0xFFF;
+ enc.patch4(opStart+4,riscv.u_type(riscv.OP_AUIPC, riscv.A2 , imm20));
+ enc.patch4(opStart+8,riscv.i_type(riscv.OP_JALR , riscv.RPC, 0, riscv.A2, imm12));
+ } else
+ throw Utils.TODO();
}
// General form: "alloc #bytes PC"
@Override public void asm(CodeGen code, SB sb) {
- sb.p("auipc a1=#calloc\n");
- sb.p("call a1+#calloc, a0");
+ sb.p("ldi a1=#1\n");
+ sb.p("auipc a2=#calloc\n");
+ sb.p("call a2+#calloc, a0");
}
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index bd3783ed..d67bd43d 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -98,8 +98,27 @@ public class Chapter21Test {
@Test public void testStringExport() throws IOException { TestC.run("stringHash"); }
@Test public void testSieve() throws IOException {
- String primes = "25[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, ]";
- TestC.run("sieve",primes);
+ // The primes
+ int[] primes = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, };
+ SB sb = new SB().p(primes.length).p("[");
+ for( int prime : primes )
+ sb.p(prime).p(", ");
+ String sprimes = sb.p("]").toString();
+
+ // Compile, link against native C; expect the above string of primes to be printed out by C
+ TestC.run("sieve",sprimes);
+
+ // Evaluate on RISC5 emulator; expect return of a array of primes in
+ // the simulated heap.
+ EvalRisc5 R5 = TestRisc5.build("sieve", 100);
+ int trap = R5.step(10000);
+ assertEquals(0,trap);
+ // Return register A0 holds sieve(100)
+ int ary = (int)R5.regs[riscv.A0];
+ // Memory layout starting at ary(length,pad, prime1, primt2, prime3, prime4)
+ assertEquals(primes.length, R5.ld4s(ary));
+ for( int i=0; i<primes.length; i++ )
+ assertEquals(primes[i], R5.ld4s(ary + 4 + i*4));
}
@Test public void testFibExport() throws IOException {
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java b/chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java
index cb5417d8..eed596e8 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java
@@ -8,23 +8,34 @@
* Load code into memory and go!
*/
-public class EvalRisc5 {
+import com.seaofnodes.simple.codegen.Encoding;
+
+import java.util.Arrays;
+
+ public class EvalRisc5 {
// Memory image, always 0-based
public final byte[] _buf;
- EvalRisc5( byte[] buf ) { _buf=buf; }
+ // GPRs
+ final long[] regs;
+
+ // PC
+ int _pc;
- //#ifndef MINIRV32_CUSTOM_MEMORY_BUS
- // #define MINIRV32_STORE4( ofs, val ) *(int*)(_buf + ofs) = val
- // #define MINIRV32_STORE2( ofs, val ) *(uint16_t*)(_buf + ofs) = val
- // #define MINIRV32_STORE1( ofs, val ) *(uint8_t*)(_buf + ofs) = val
- // #define MINIRV32_LOAD4( ofs ) *(int*)(_buf + ofs)
- // #define MINIRV32_LOAD2( ofs ) *(uint16_t*)(_buf + ofs)
- // #define MINIRV32_LOAD1( ofs ) *(uint8_t*)(_buf + ofs)
- // #define MINIRV32_LOAD2_SIGNED( ofs ) *(int16_t*)(_buf + ofs)
- // #define MINIRV32_LOAD1_SIGNED( ofs ) *(int8_t*)(_buf + ofs)
- //#endif
+ // Start of free memory for allocation
+ int _heap;
+
+ // Cycle counters
+ int _cycle;
+
+ EvalRisc5( byte[] buf, int stackSize ) {
+ _buf = buf;
+ regs = new long[32];
+ // Stack grows down, heap grows up
+ regs[2/*RSP*/] = _heap = stackSize;
+ _pc = 0;
+ }
// Little endian
public int ld1s(int x) { return _buf[x ] ; }
@@ -39,16 +50,6 @@ public class EvalRisc5 {
public void st4(int x, int val) { st2(x,val); st2(x+2,val>>16); }
public void st8(int x, long val) { st4(x,(int)val); st2(x+4,(int)(val>>32)); }
-
- // GPRs
- final long[] regs = new long[32];
-
- // PC
- int _pc;
-
- // Cycle counters
- int _cycle;
-
// Note: only a few bits are used. (Machine = 3, User = 0)
// Bits 0..1 = privilege.
// Bit 2 = WFI (Wait for interrupt)
@@ -76,6 +77,7 @@ public class EvalRisc5 {
break;
}
+ // Load instruction from image buffer at PC
ir = ld4s( pc );
int rdid = (ir >> 7) & 0x1f;
@@ -95,14 +97,24 @@ public class EvalRisc5 {
}
case 0x67: { // JALR (0b1100111)
int imm = ir >> 20;
+
int imm_se = imm | (( (imm & 0x800)!=0 ) ? 0xfffff000 : 0);
rval = pc + 4;
pc = ( ((int)regs[ (ir >> 15) & 0x1f ] + imm_se) & ~1) - 4;
// Return from top-level ; exit sim
if( pc+4==0 ) {
- if( rdid!=0 ) regs[rdid] = rval;
+ if( rdid!=0 ) regs[rdid] = rval; // Write PC into register before exit
break outer;
}
+ // Inline CALLOC effect
+ if( pc == Encoding.SENTINAL_CALLOC ) {
+ int size = (int)(regs[10]*regs[11]);
+ regs[10] = _heap; // Return next free address
+ // Pre-zeroed; epsilon (null) collector, never recycles memory so always zero
+ // Arrays.fill(_buf,_heap,_heap+size, (byte) 0 );
+ _heap += size;
+ pc = (int)(rval - 4); // Unwind PC, as-if returned from calloc
+ }
break;
}
case 0x63: { // Branch (0b1100011)
@@ -142,6 +154,7 @@ public class EvalRisc5 {
case 3: rval = ld8 ( rsval ); break;
case 4: rval = ld1z( rsval ); break;
case 5: rval = ld2z( rsval ); break;
+ case 6: rval = ld4s( rsval ); break;
default: trap = (2+1);
}
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java b/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java
index 9c64fe9f..8b9b8884 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java
@@ -18,17 +18,13 @@ public abstract class TestRisc5 {
public static EvalRisc5 build( String dir, String file, int arg ) throws IOException {
// Compile and export Simple
String src = Files.readString(Path.of(dir+"/"+file+".smp"));
- CodeGen code = new CodeGen(src).driver(CodeGen.Phase.Encoding,"riscv", "SystemV");
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.RegAlloc,"riscv", "SystemV").encode(true);
// Image
- byte[] image = new byte[1<<20]; // A megabyte
- EvalRisc5 R5 = new EvalRisc5(image);
+ byte[] image = new byte[1<<20]; // A megabyte (1024*1024 bytes)
+ EvalRisc5 R5 = new EvalRisc5(image, 1<<16);
// Code at offset 0
System.arraycopy(code._encoding.bits(), 0, image, 0, code._encoding.bits().length);
- // Program start
- R5._pc = 0;
- // Stack starts at 64K and goes down (runs into code)
- R5.regs[riscv.SP] = 1<<16;
// Initial incoming int arg
R5.regs[riscv.A0] = arg;
// malloc memory starts at 64K and goes up
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/jig.smp b/chapter21/src/test/java/com/seaofnodes/simple/progs/jig.smp
index c1c50c03..3d01f80f 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/progs/jig.smp
+++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/jig.smp
@@ -1,277 +1,11 @@
// -*- mode: java; -*-
-while(-----arg) {
- while(-arg) {
- while(-----arg*---0) {
- int N=--false==false<--arg;
- while(N<-4==N) {
- N=N+N;
- }
- }
- {
- int kzEl_r7EYz=3*----0!=-arg<(37*--97!=0/arg==arg)<=-(--arg!=0);
- while(kzEl_r7EYz<---1) {
- kzEl_r7EYz=kzEl_r7EYz+kzEl_r7EYz*arg>=24;
- if(7) continue;
- kzEl_r7EYz=false;
- if(-kzEl_r7EYz+arg<-3) continue;
- else {
- while(kzEl_r7EYz) continue;
- arg=----3;
- kzEl_r7EYz=-(-----arg*1>-kzEl_r7EYz);
- int v2uF_4ba=9;
- }
- }
- }
- int pjcp7rv=arg;
- {
- int m2ya3=--arg-pjcp7rv;
- while(m2ya3<-----pjcp7rv>=pjcp7rv+--pjcp7rv!=---pjcp7rv!=-arg<---(-m2ya3)>m2ya3<=-----true>14!=--m2ya3) {
- m2ya3=m2ya3+-(--0<=false<pjcp7rv/arg<=-true);
- while((--m2ya3)<--arg<-----arg*false!=arg<pjcp7rv*arg) {
- pjcp7rv=-3+-arg;
- break;
- }
- while(-3) {
- while(67+0-61) m2ya3=m2ya3;
- if(----pjcp7rv==---(---arg)) pjcp7rv=0!=-23;
- else pjcp7rv=----89;
- while(m2ya3!=m2ya3<pjcp7rv) m2ya3=1;
- while(--arg<=pjcp7rv) pjcp7rv=-32<=-m2ya3+62;
- }
- break;
- }
- }
- {
- int arg=-1<-9!=(-arg>=-pjcp7rv>=arg<=arg);
- while(arg<-arg) {
- arg=arg+--arg;
- {
- while((--93)--pjcp7rv*-pjcp7rv+arg) arg=0-(6>=(--(---41/(0))!=--pjcp7rv)>=---2*33);
- pjcp7rv=11;
- int c=pjcp7rv;
- if(--107) break;
- else break;
- }
- }
- }
- pjcp7rv=pjcp7rv;
- int aR0Wkua=-pjcp7rv==pjcp7rv;
- {
- if(-0!=-0) while(-true) break;
- else {
- while(aR0Wkua) pjcp7rv=-0/pjcp7rv;
- pjcp7rv=pjcp7rv;
- }
- }
+while(0) {
+ int v0=0;
+ while(1>>arg+0>>>0<=0) {
+ v0=1+arg/0;
+ while(1)
+ if(0/--v0+arg) 0;
+ v0=-21;
}
- if(-arg) {
- {
- int Isdlt0fr91=0!=arg;
- while(Isdlt0fr91<-Isdlt0fr91==-Isdlt0fr91+true) {
- Isdlt0fr91=Isdlt0fr91+-1!=true;
- if(-arg) if(--arg<=Isdlt0fr91) Isdlt0fr91=-Isdlt0fr91;
- int i=---arg<---arg!=--40;
- {
- int jVX43Ln4Dm=-(6)==-Isdlt0fr91/----0;
- while(jVX43Ln4Dm<--(3-3)) {
- jVX43Ln4Dm=jVX43Ln4Dm+-0<25;
- i=24<--(jVX43Ln4Dm);
- }
- }
- i=(arg!=----false>=7);
- int Te=5>-arg;
- break;
- }
- }
- arg=arg!=--true/arg;
- {
- int UX=arg;
- while(UX<-3*arg) {
- UX=UX+arg/-1;
- arg=-3--(-UX--47<arg==--arg==arg)/arg--UX>=-arg;
- if(---12) while(-UX) break;
- break;
- }
- }
- continue;
- }
- if(arg) arg=--0;
- else if(1) continue;
- int DtTlhjYq=19==arg;
- {
- arg=--DtTlhjYq<=(DtTlhjYq/---DtTlhjYq<=-DtTlhjYq);
- if(---arg) continue;
- else {
- int Zsl=40;
- while(Zsl<--Zsl--false>((Zsl))==Zsl!=--DtTlhjYq-DtTlhjYq-DtTlhjYq) {
- Zsl=Zsl+arg;
- }
- }
- if((arg)) if(-DtTlhjYq) {
- }
- else while(((2)==3*arg/DtTlhjYq)<=0==---arg) return false;
- else {
- int lwbF=arg>=0;
- while(lwbF<57) {
- lwbF=lwbF+--(-arg+lwbF)>=-2>=arg!=arg;
- arg=----0+0;
- while(49) break;
- if(true) DtTlhjYq=-----arg;
- DtTlhjYq=0!=-----(0);
- }
- }
- arg=---arg!=DtTlhjYq/--0;
- DtTlhjYq=-DtTlhjYq/(--arg<arg);
- if(32) {
- int q=-DtTlhjYq;
- while(q<arg*(0*q)/0) {
- q=q+DtTlhjYq;
- DtTlhjYq=arg;
- }
- }
- else if(--arg) if(15) break;
- else arg=0==arg<=-55>DtTlhjYq;
- else {
- }
- DtTlhjYq=-0;
- {
- while((0)<-arg) DtTlhjYq=-DtTlhjYq;
- }
- if(30/--(arg)>=0) DtTlhjYq=-0>=arg;
- else {
- int Y2wcIQJ=--DtTlhjYq*---11;
- if(arg==arg) {
- Y2wcIQJ=-----Y2wcIQJ;
- Y2wcIQJ=Y2wcIQJ<7;
- if(DtTlhjYq) arg=arg;
- else break;
- while(-arg!=-31==(false<=-15>=-DtTlhjYq+--6*-----Y2wcIQJ<=---arg!=-Y2wcIQJ<=---0<-arg*--Y2wcIQJ)) DtTlhjYq=arg!=3;
- }
- continue;
- }
- arg=DtTlhjYq;
- arg=--3/(---arg)>=80>=-DtTlhjYq<=DtTlhjYq;
- arg=51+---(-true)!=arg!=----1==-DtTlhjYq;
- if(11<=arg) if((arg)+79<32+(-arg)) continue;
- else if(true==DtTlhjYq) break;
- break;
- }
-}
-if(arg!=62==arg) {
- while(---arg) {
- {
- int bhmDacPM=arg/arg;
- while(bhmDacPM<arg) {
- bhmDacPM=bhmDacPM+80*((-bhmDacPM)/---bhmDacPM>1)<bhmDacPM-2!=7;
- arg=-0;
- arg=bhmDacPM>=-arg+-arg;
- break;
- }
- }
- int arg=true;
- arg=arg<=arg;
- {
- int KlC=30;
- while(KlC<-2) {
- KlC=KlC+-1!=25<=-KlC>KlC>----0;
- int Ij=arg>=-arg<=---10;
- {
- int LAbgurVa2R=-arg!=Ij;
- while(LAbgurVa2R<-true) {
- LAbgurVa2R=LAbgurVa2R+Ij;
- KlC=-LAbgurVa2R;
- Ij=42*(-Ij>true);
- while(Ij) arg=KlC;
- KlC=-----7>-(--KlC<--7)==-LAbgurVa2R;
- }
- }
- int a=Ij<=-KlC;
- if(Ij) {
- int r1W=a!=-false;
- }
- else {
- arg=56>=Ij;
- while(54) break;
- arg=8>=-(a<--Ij)/a>=-a-KlC;
- }
- int Yt_T=KlC;
- arg=KlC;
- }
- }
- if(----false/--arg/12+-----0) if(-9+-arg) while(arg!=(arg)) arg=--1>=-71-arg!=---(--arg*11+102)/--arg;
- else if(----arg) continue;
- if(-arg-arg) {
- arg=-(-arg)*--(-3)<(-7==-arg----arg);
- {
- int arg=arg;
- while(arg<-0>arg==-arg-(-arg>1+11)) {
- arg=arg+6-arg!=--0>---30>=---arg<=arg/(3)+---arg;
- }
- }
- arg=-arg+arg;
- arg=--47+-arg<1>arg*(-arg==-arg--0>3);
- arg=(----arg)!=arg+--59;
- arg=--4+arg==-(arg)-arg;
- }
- else {
- while(--true-----true*-25+-18>arg>=-----(-arg)---13) {
- arg=-0+--true<false;
- continue;
- }
- arg=true<=arg;
- break;
- }
- arg=arg*22<--(0+-arg);
- {
- continue;
- }
- }
- arg=1*---((3<=true)==---2);
- arg=7+-(-1);
- return arg+--true;
-}
-else {
- int o3ypEsewxM=-(---arg);
- int vzXB=(-(---11<=--o3ypEsewxM>=--0))<=-0/-arg;
- int L=-arg;
- int B4mHcrf=---vzXB;
- int oZWGdzZl=-o3ypEsewxM;
- int K6tQqa1=11;
- while(0!=--L) {
- int sdZfTM=vzXB*true+K6tQqa1;
- while(sdZfTM<false) {
- sdZfTM=sdZfTM+arg;
- sdZfTM=oZWGdzZl;
- K6tQqa1=-K6tQqa1;
- arg=---K6tQqa1;
- while((3+-K6tQqa1)<oZWGdzZl) {
- if(-----(-1)) sdZfTM=-false;
- {}
- }
- K6tQqa1=vzXB!=-(B4mHcrf+-7>false);
- sdZfTM=vzXB;
- }
- }
- L=false;
- while(31) B4mHcrf=arg;
- oZWGdzZl=-0<--oZWGdzZl<=--2;
- if(K6tQqa1>=20<=46) {
- if(-1+-L) if(oZWGdzZl) {
- int wmhv=-----0;
- }
- int arg=0;
- o3ypEsewxM=---(oZWGdzZl);
- return -oZWGdzZl/0;
- }
- else if(arg) {
- int yKk5=B4mHcrf>=4>K6tQqa1<-B4mHcrf/o3ypEsewxM;
- return -K6tQqa1;
- }
- else {
- if(---0) {
- {}
- {}
- }
- return o3ypEsewxM;
- }
}
+while(0) {}