Hi, I am currently working on my GSoC project and while testing through 0-day test service, I hit the following error: drivers/iio/chemical/bme680_core.o: In function `bme680_compensate_gas': drivers/iio/chemical/bme680_core.c:450: undefined reference to `__divdi3' vim +450 drivers/iio/chemical/bme680_core.c 417 418 /* 419 * Taken from Bosch BME680 API: 420 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L973 421 * 422 * Returns gas measurement in Ohm. Output value of "82986" represent 82986 ohms. 423 */ 424 static u32 bme680_compensate_gas(struct bme680_data *data, u16 gas_res_adc, 425 u8 gas_range) 426 { 427 struct bme680_calib *calib = &data->bme680; 428 s64 var1; 429 u64 var2; 430 s64 var3; 431 u32 calc_gas_res; 432 433 /* Look up table 1 for the possible gas range values */ 434 u32 lookupTable1[16] = {2147483647u, 2147483647u, 2147483647u, 435 2147483647u, 2147483647u, 2126008810u, 436 2147483647u, 2130303777u, 2147483647u, 437 2147483647u, 2143188679u, 2136746228u, 438 2147483647u, 2126008810u, 2147483647u, 439 2147483647u}; 440 /* Look up table 2 for the possible gas range values */ 441 u32 lookupTable2[16] = {4096000000u, 2048000000u, 1024000000u, 442 512000000u, 255744255u, 127110228u, 64000000u, 443 32258064u, 16016016u, 8000000u, 4000000u, 444 2000000u, 1000000u, 500000u, 250000u, 125000u}; 445 446 var1 = ((1340 + (5 * (s64) calib->range_sw_err)) * 447 ((s64) lookupTable1[gas_range])) >> 16; 448 var2 = (((s64) ((s64) gas_res_adc << 15) - 16777216) + var1); 449 var3 = (((s64) lookupTable2[gas_range] * (s64) var1) >> 9); > 450 calc_gas_res = (u32) ((var3 + ((s64) var2 >> 1)) / (s64) var2); 451 452 return calc_gas_res; 453 } Now, I understood the problem of 64bit divison and how gcc places '__divdi3()' https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html to support the "freestanding" environment and support architectures which don't have such datatypes. And I need to use div64_s64() or hack around do_div() to solve the issue. Just out of curiosity, I decided to disassemble this particular function to see __divdi3 and couldn't find it! (gdb) disassemble bme680_compensate_gas Dump of assembler code for function bme680_compensate_gas: 0x0000000000000000 <+0>: call 0x5 <bme680_compensate_gas+5> 0x0000000000000005 <+5>: sub rsp,0x88 0x000000000000000c <+12>: movabs rcx,0x7eb851ea7fffffff 0x0000000000000016 <+22>: movzx edx,dl 0x0000000000000019 <+25>: mov rax,QWORD PTR gs:0x28 0x0000000000000022 <+34>: mov QWORD PTR [rsp+0x80],rax 0x000000000000002a <+42>: xor eax,eax 0x000000000000002c <+44>: movabs rax,0x7fffffff7fffffff 0x0000000000000036 <+54>: movabs r8,0x7ef9db217fffffff 0x0000000000000040 <+64>: movabs r9,0x7f5c28f47fbe76c7 0x000000000000004a <+74>: mov QWORD PTR [rsp],rax 0x000000000000004e <+78>: mov QWORD PTR [rsp+0x8],rax 0x0000000000000053 <+83>: movzx esi,si 0x0000000000000056 <+86>: mov QWORD PTR [rsp+0x20],rax 0x000000000000005b <+91>: mov QWORD PTR [rsp+0x38],rax 0x0000000000000060 <+96>: movabs rax,0x7a120000f4240000 0x000000000000006a <+106>: mov QWORD PTR [rsp+0x40],rax 0x000000000000006f <+111>: movabs rax,0x1e8480003d090000 0x0000000000000079 <+121>: mov QWORD PTR [rsp+0x10],rcx 0x000000000000007e <+126>: mov QWORD PTR [rsp+0x48],rax 0x0000000000000083 <+131>: movabs rax,0x7938c540f3e58ff 0x000000000000008d <+141>: mov QWORD PTR [rsp+0x18],r8 0x0000000000000092 <+146>: mov QWORD PTR [rsp+0x50],rax 0x0000000000000097 <+151>: movabs rax,0x1ec381003d09000 0x00000000000000a1 <+161>: mov QWORD PTR [rsp+0x28],r9 0x00000000000000a6 <+166>: mov QWORD PTR [rsp+0x58],rax 0x00000000000000ab <+171>: movabs rax,0x7a120000f46290 0x00000000000000b5 <+181>: mov QWORD PTR [rsp+0x30],rcx 0x00000000000000ba <+186>: mov QWORD PTR [rsp+0x60],rax 0x00000000000000bf <+191>: movabs rax,0x1e8480003d0900 0x00000000000000c9 <+201>: mov ecx,DWORD PTR [rsp+rdx*4] 0x00000000000000cc <+204>: mov QWORD PTR [rsp+0x68],rax 0x00000000000000d1 <+209>: movabs rax,0x7a120000f4240 0x00000000000000db <+219>: shl rsi,0xf 0x00000000000000df <+223>: mov QWORD PTR [rsp+0x70],rax 0x00000000000000e4 <+228>: movabs rax,0x1e8480003d090 0x00000000000000ee <+238>: mov QWORD PTR [rsp+0x78],rax 0x00000000000000f3 <+243>: movsx rax,BYTE PTR [rdi+0x2f] 0x00000000000000f8 <+248>: lea rax,[rax+rax*4+0x53c] 0x0000000000000100 <+256>: imul rax,rcx 0x0000000000000104 <+260>: sar rax,0x10 0x0000000000000108 <+264>: lea rsi,[rax+rsi*1-0x1000000] 0x0000000000000110 <+272>: mov rcx,rax 0x0000000000000113 <+275>: mov eax,DWORD PTR [rsp+rdx*4+0x40] 0x0000000000000117 <+279>: mov rdx,rsi 0x000000000000011a <+282>: sar rdx,1 0x000000000000011d <+285>: imul rax,rcx 0x0000000000000121 <+289>: sar rax,0x9 0x0000000000000125 <+293>: add rax,rdx 0x0000000000000128 <+296>: cqo 0x000000000000012a <+298>: idiv rsi 0x000000000000012d <+301>: mov rdi,QWORD PTR [rsp+0x80] 0x0000000000000135 <+309>: xor rdi,QWORD PTR gs:0x28 0x000000000000013e <+318>: jne 0x148 <bme680_compensate_gas+328> 0x0000000000000140 <+320>: add rsp,0x88 0x0000000000000147 <+327>: ret 0x0000000000000148 <+328>: call 0x14d End of assembler dump. So, we have here: 0x000000000000012a <+298>: idiv rsi Now, my question is, will __divdi3() be generated when I compile using -m32 gcc flag or make ARCH=i386 ? My machine is x86_64 and therefore idiv instruction is used instead of referencing __divdi3(). Isn't it ? Thanks. -- Himanshu Jha Undergraduate Student Department of Electronics & Communication Guru Tegh Bahadur Institute of Technology _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies