Variable floating point value is missing from data memory

I am a master student and am currently working on my summer final project which focuses on MIPS processor design with FPU and implementation in FPGA.

The instructions I am going to implement depend on the cross compiler I am using. So, from the point of view of a hardware designer, I started the project by first looking at the instructions that could be generated from the compiler.

For integer design (core core design) I wrote some C codes, for example a simple one:

int main ()
{
int a,b,c;
a=1;
b=2;
c=a+2;
}

      

Simple addition, the compiler gives the assembler codes: (I just posted the assembly codes mostly because I didn't plan on running the operating system on my MIPS)

00400168 <main>:
  400168:       27bdffe8        addiu   sp,sp,-24
  40016c:       afbe0010        sw      s8,16(sp)
  400170:       03a0f021        move    s8,sp
  400174:       24020001        li      v0,1
  400178:       afc20008        sw      v0,8(s8)
  40017c:       24020002        li      v0,2
  400180:       afc20004        sw      v0,4(s8)
  400184:       8fc20008        lw      v0,8(s8)
  400188:       00000000        nop
  40018c:       20420002        addi    v0,v0,2
  400190:       afc20000        sw      v0,0(s8)
  400194:       03c0e821        move    sp,s8
  400198:       8fbe0010        lw      s8,16(sp)
  40019c:       27bd0018        addiu   sp,sp,24
  4001a0:       03e00008        jr      ra

      

I like to understand the assembly code which can help me understand MIPS architecture better, and based on ordering instructions, I can create a compiler based hazard detection unit.

From these 4 instructions you can see:

  400174:       24020001        li      v0,1
  400178:       afc20008        sw      v0,8(s8)
  40017c:       24020002        li      v0,2
  400180:       afc20004        sw      v0,4(s8)

      

The compiler loads 1, 2 into the variable a, b. For integer assembly code, I don't understand the problems.

Ok, let's move on to the floating point block, also, I wrote a very similar C:

Floating point testing C code

void main ()
{
float a,b,c;
a=1;
b=2;
c=a+b;
}

      

Now the build codes are very different:

00400168 <main>:
  400168:       27bdffe8        addiu   sp,sp,-24
  40016c:       afbe0010        sw      s8,16(sp)
  400170:       03a0f021        move    s8,sp
  400174:       c7808004        lwc1    $f0,-32764(gp)
  400178:       00000000        nop
  40017c:       e7c00008        swc1    $f0,8(s8)
  400180:       c7808008        lwc1    $f0,-32760(gp)
  400184:       00000000        nop
  400188:       e7c00004        swc1    $f0,4(s8)
  40018c:       c7c20008        lwc1    $f2,8(s8)
  400190:       c7c00004        lwc1    $f0,4(s8)
  400194:       00000000        nop
  400198:       46001000        add.s   $f0,$f2,$f0
  40019c:       e7c00000        swc1    $f0,0(s8)
  4001a0:       03c0e821        move    sp,s8
  4001a4:       8fbe0010        lw      s8,16(sp)
  4001a8:       27bd0018        addiu   sp,sp,24
  4001ac:       03e00008        jr      ra
  4001b0:       00000000        nop

      

Don't like solid code, these 6 commands look like a program loading the value of a variable from data memory using the li command :

  400174:       c7808004        lwc1    $f0,-32764(gp)
  400178:       00000000        nop
  40017c:       e7c00008        swc1    $f0,8(s8)
  400180:       c7808008        lwc1    $f0,-32760(gp)
  400184:       00000000        nop
  400188:       e7c00004        swc1    $f0,4(s8)

      

Here's the problem: I just can't figure out what is the value stored in -32764 (gp) and f0, -32760 (gp) because there are no SW instructions that try to store data in those address.

Here is the complete assembly code generated by the compiler:

floatadd:     file format elf32-bigmips


Disassembly of section .init:

00400018 <_init>:
  400018:       27bdffe0        addiu   sp,sp,-32
  40001c:       afbf0014        sw      ra,20(sp)
  400020:       0c10003a        jal     4000e8 <frame_dummy>
  400024:       00000000        nop
  400028:       0c10006d        jal     4001b4 <__do_global_ctors_aux>
  40002c:       00000000        nop
  400030:       8fbf0014        lw      ra,20(sp)
  400034:       27bd0020        addiu   sp,sp,32
  400038:       03e00008        jr      ra
  40003c:       00000000        nop

Disassembly of section .text:

00400040 <_ftext>:
  400040:       27bdffe0        addiu   sp,sp,-32
  400044:       afb10014        sw      s1,20(sp)
  400048:       3c110040        lui     s1,0x40
  40004c:       9222126c        lbu     v0,4716(s1)
  400050:       afbf0018        sw      ra,24(sp)
  400054:       14400019        bnez    v0,4000bc <_ftext+0x7c>
  400058:       afb00010        sw      s0,16(sp)
  40005c:       3c100040        lui     s0,0x40
  400060:       8e021260        lw      v0,4704(s0)
  400064:       00000000        nop
  400068:       8c430000        lw      v1,0(v0)
  40006c:       00000000        nop
  400070:       10600009        beqz    v1,400098 <_ftext+0x58>
  400074:       24420004        addiu   v0,v0,4
  400078:       0060f809        jalr    v1
  40007c:       ae021260        sw      v0,4704(s0)
  400080:       8e021260        lw      v0,4704(s0)
  400084:       00000000        nop
  400088:       8c430000        lw      v1,0(v0)
  40008c:       00000000        nop
  400090:       1460fff9        bnez    v1,400078 <_ftext+0x38>
  400094:       24420004        addiu   v0,v0,4
  400098:       3c020000        lui     v0,0x0
  40009c:       24420000        addiu   v0,v0,0
  4000a0:       10400005        beqz    v0,4000b8 <_ftext+0x78>
  4000a4:       24020001        li      v0,1
  4000a8:       3c040040        lui     a0,0x40
  4000ac:       0c000000        jal     0 <_init-0x400018>
  4000b0:       24840244        addiu   a0,a0,580
  4000b4:       24020001        li      v0,1
  4000b8:       a222126c        sb      v0,4716(s1)
  4000bc:       8fbf0018        lw      ra,24(sp)
  4000c0:       8fb10014        lw      s1,20(sp)
  4000c4:       8fb00010        lw      s0,16(sp)
  4000c8:       03e00008        jr      ra
  4000cc:       27bd0020        addiu   sp,sp,32

004000d0 <call___do_global_dtors_aux>:
  4000d0:       27bdffe8        addiu   sp,sp,-24
  4000d4:       afbf0010        sw      ra,16(sp)
  4000d8:       8fbf0010        lw      ra,16(sp)
  4000dc:       00000000        nop
  4000e0:       03e00008        jr      ra
  4000e4:       27bd0018        addiu   sp,sp,24

004000e8 <frame_dummy>:
  4000e8:       3c020000        lui     v0,0x0
  4000ec:       27bdffe8        addiu   sp,sp,-24
  4000f0:       3c040040        lui     a0,0x40
  4000f4:       3c050040        lui     a1,0x40
  4000f8:       24420000        addiu   v0,v0,0
  4000fc:       afbf0010        sw      ra,16(sp)
  400100:       24840244        addiu   a0,a0,580
  400104:       10400003        beqz    v0,400114 <frame_dummy+0x2c>
  400108:       24a51270        addiu   a1,a1,4720
  40010c:       0c000000        jal     0 <_init-0x400018>
  400110:       00000000        nop
  400114:       3c040040        lui     a0,0x40
  400118:       8c831258        lw      v1,4696(a0)
  40011c:       3c020000        lui     v0,0x0
  400120:       10600007        beqz    v1,400140 <frame_dummy+0x58>
  400124:       24590000        addiu   t9,v0,0
  400128:       24841258        addiu   a0,a0,4696
  40012c:       13200004        beqz    t9,400140 <frame_dummy+0x58>
  400130:       00000000        nop
  400134:       8fbf0010        lw      ra,16(sp)
  400138:       03200008        jr      t9
  40013c:       27bd0018        addiu   sp,sp,24
  400140:       8fbf0010        lw      ra,16(sp)
  400144:       00000000        nop
  400148:       03e00008        jr      ra
  40014c:       27bd0018        addiu   sp,sp,24

00400150 <call_frame_dummy>:
  400150:       27bdffe8        addiu   sp,sp,-24
  400154:       afbf0010        sw      ra,16(sp)
  400158:       8fbf0010        lw      ra,16(sp)
  40015c:       00000000        nop
  400160:       03e00008        jr      ra
  400164:       27bd0018        addiu   sp,sp,24

00400168 <main>:
  400168:       27bdffe8        addiu   sp,sp,-24
  40016c:       afbe0010        sw      s8,16(sp)
  400170:       03a0f021        move    s8,sp
  400174:       c7808004        lwc1    $f0,-32764(gp)
  400178:       00000000        nop
  40017c:       e7c00008        swc1    $f0,8(s8)
  400180:       c7808008        lwc1    $f0,-32760(gp)
  400184:       00000000        nop
  400188:       e7c00004        swc1    $f0,4(s8)
  40018c:       c7c20008        lwc1    $f2,8(s8)
  400190:       c7c00004        lwc1    $f0,4(s8)
  400194:       00000000        nop
  400198:       46001000        add.s   $f0,$f2,$f0
  40019c:       e7c00000        swc1    $f0,0(s8)
  4001a0:       03c0e821        move    sp,s8
  4001a4:       8fbe0010        lw      s8,16(sp)
  4001a8:       27bd0018        addiu   sp,sp,24
  4001ac:       03e00008        jr      ra
  4001b0:       00000000        nop

004001b4 <__do_global_ctors_aux>:
  4001b4:       3c020040        lui     v0,0x40
  4001b8:       2442124c        addiu   v0,v0,4684
  4001bc:       8c44fffc        lw      a0,-4(v0)
  4001c0:       27bdffe0        addiu   sp,sp,-32
  4001c4:       2403ffff        li      v1,-1
  4001c8:       afb00010        sw      s0,16(sp)
  4001cc:       afbf0018        sw      ra,24(sp)
  4001d0:       afb10014        sw      s1,20(sp)
  4001d4:       10830008        beq     a0,v1,4001f8 <__do_global_ctors_aux+0x44>
  4001d8:       2450fffc        addiu   s0,v0,-4
  4001dc:       2411ffff        li      s1,-1
  4001e0:       0080f809        jalr    a0
  4001e4:       2610fffc        addiu   s0,s0,-4
  4001e8:       8e040000        lw      a0,0(s0)
  4001ec:       00000000        nop
  4001f0:       1491fffb        bne     a0,s1,4001e0 <__do_global_ctors_aux+0x2c>
  4001f4:       00000000        nop
  4001f8:       8fbf0018        lw      ra,24(sp)
  4001fc:       8fb10014        lw      s1,20(sp)
  400200:       8fb00010        lw      s0,16(sp)
  400204:       03e00008        jr      ra
  400208:       27bd0020        addiu   sp,sp,32

0040020c <call___do_global_ctors_aux>:
  40020c:       27bdffe8        addiu   sp,sp,-24
  400210:       afbf0010        sw      ra,16(sp)
  400214:       8fbf0010        lw      ra,16(sp)
  400218:       00000000        nop
  40021c:       03e00008        jr      ra
  400220:       27bd0018        addiu   sp,sp,24

Disassembly of section .fini:

00400224 <_fini>:
  400224:       27bdffe0        addiu   sp,sp,-32
  400228:       afbf0014        sw      ra,20(sp)
  40022c:       0c100010        jal     400040 <_ftext>
  400230:       00000000        nop
  400234:       8fbf0014        lw      ra,20(sp)
  400238:       27bd0020        addiu   sp,sp,32
  40023c:       03e00008        jr      ra
  400240:       00000000        nop

      

I am not good at MIPS assembly, can someone please explain where the floating point variable 'value 1 and 2?

+3


source to share


1 answer


About your question

ELF executables can have one or more sections filled with static data (strings, floats, numbers, etc.) used by the program.
These sections are loaded into memory by the loader with the rest of the program, thus avoiding confusion of code and data and reducing the size of the code.

For ELF on MIPS systems, you should refer to this where there is this nice image:

MIPS ELF Sections

As you can see, this is $gp

used to address the .sdata and .sbss sections, where the leading s stands for small.

All of these efforts are made to minimize the size of the code, since the $gp

compiler can generate 16-bit offsets (versus regular 32-bit ones) with the help of the compiler.
Since the offset is signed, it $gp

is placed in the middle (at most) of the 64 KiB area formed by .sdata + .sbss.



Your floating point value is not directly encoded in the instructions because the FP command does not accept immediate results , instead they are stored in the readonly section and loaded from there.

About your goal

Why, in the end, do you care?
If your goal is to design a MIPS ISA implementation, just select a specific ISA (MIPS32 I? MIPS32 IV? MIPS 64?). Get the docs, get the whole picture, and flesh out the microarchitecture.

If the instruction is a valid instruction according to your chosen ISA, then your implementation should be able to execute it, don't worry about what the compilers do, they've grown, they can take care of themselves, and finally if the code you are executing is broken who needs it? Until then, it is valid.

This will help you:

MIPS32 ™ Architecture for Programmers Volume I: Introduction to the MIPS32 ™ Architecture MIPS32 ™ Architecture for Programmers Volume II: MIPS32 ™ Instruction Set

+4


source







All Articles