November 14, 2007

Understanding Win64 developement environment

Since Sun's developer doesn't seem to know Win64 development environment by Bugzilla #227049, I explain it

There is 2 CPU arch for Win64

  • IA64 (aka Itanium)
  • x64 (aka AMD64, x86_64)

Win64 tools such as complier and assember are included in the following products.

Visual Studio 2005 Express Edition doesn't have Win64 complier and linker. If you want to get Win64 build environment by non-fee, you have to use Platfrom SDK for Windows Server 2003. Platform SDK has version 14.x of CL.EXE (as same as major version of Visual Studio 2005).

Also, how about Platform SDK for Windows Vista? It is not good chooise. Becasue, it doesn't include assember such as ML64.EXE. Although I don't know why Microsoft decides it has no assember command, we must buy VS2005 STD/PRO if you need latest compiler and assember.

December 1, 2006

Why does new SDK for Vista have no ML64.EXE?

Although new Platform SDK for Windows Vista is available in Download Center, this SDK doesn't have MFC libraries and ML64.EXE (Microsoft Macro Assembler for x64). I believe, althugh these tools and libralies are included in Visual Studio 2005 Professional Edition, these were included in Windows Server 2003 SDK.

Why were these removed from SDK??

June 24, 2005

How to get IME settings such as converted text color

Windows IME (Input Method Editor) has some mode to use Imm API.

  • Half-aware
  • Full-aware

Half-aware mode

By handling a few windows message, you can use inline-input of IME string. And, IME will handle about rendering.

Full-aware mode

By handling many windows message, you can use inline-input of IME string. Since IME doesn't handle about rendering and application must render strings...

Some application uses full-aware mode (ex. Microsoft Office, FireFox). Although Active IMM support on Mozilla/FireFox is written by me, many enhanced functions of IME are implemented by me too. Although Redering code is implemented by Frank Tang who was Netscape Engineer, there is a important problem about this code.

  • It uses hard-corded value for IME color. If we want to change it, we cannot do it

How can we get this color from IME? We should use sepecfic API each IMEs. Microsoft and Just System (known as ATOK) provide a document how to use configuration shared library.

Microsoft (MSIME)
http://msdn.microsoft.com/library/en-us/dnime/html/imeshare.asp
Just System (ATOK)
http://www.justsystem.co.jp/tech/atok/amet12_00.html

Unfortunatelly, this document of MSIME is useless. Because, although this document explains hwo to use IMESHARE.DLL API, there is no header file into SDK. Sit MS! So I have reseached how to use IMESHARE API.

header may be this...

class CIMEShare
{
public:
    virtual void __cdecl CustomizeIMEShare();
    virtual BOOL __cdecl FSupportSty(UINT, UINT);
    virtual LID __cdecl LidSetLid(LID);
    virtual LID __cdecl LidGetLid();
    virtual DWORD __cdecl DwGetIMEStyle(const UINT, const UINT);
    virtual BOOL __cdecl FDeleteIMEShare();
    virtual BOOL __cdecl DwGetIMEStyleCpl(const UINT, const UINT);
    virtual BOOL __cdecl FSetIMEStyleCpl(const UINT, const UINT, DWORD);
    virtual BOOL __cdecl FSaveIMEShareCpl();
};

typedef CIMEShare * (WINAPI *PIMESHARECREATE) (void);

#define IMESATTR_INPUT 1
#define IMESATTR_TARGET_CONVERTED 2
#define IMESATTR_CONVERTED 3
#define IMESATTR_TARGET_NOTCONVERTED 4

#define IdstyIMEShareSubText 0
#define IdstyIMEShareSubBack 1
#define IdstyIMEShareSubUl 2
#define IdstyIMEShareFBold 0x100
#define IdstyIMEShareFItalic 0x200
#define IdstyIMEShareFUl 0x300
#define IdstyIMEShareUKul 0x400
#define IdstyIMEShareFWinCol 0x500
#define IdstyIMEShareFFundCol 0x600
#define IdstyIMEShareFRGBCol 0x700
#define IdstyIMEShareFSpecCol 0x800
#define IdstyIMEShareRGBCol 0x900

#define IMESTY_UL_NONE 0x7d2
#define IMESTY_UL_SINGLE (IMESTY_UL_NONE + 1)
#define IMESTY_UL_DOTTED (IMESTY_UL_NONE + 3)

How to use IMESHARE API.

hImeShare = LoadLibrary(_T("IMESHARE.DLL"));
if (hImeShare)
{
  pfnImeShareCreate = (PIMESHARECREATE) GetProcAddress(hImeShare, "PIMEShareCreate");
  if (pfnImeShareCreate)
  {
    CIMEShare *pIMEShare = pfnImeShareCreate();
    if (pIMEShare)
    {
      DWORD dwColor = pIMEShare->DwGetIMEStyle(IMESATTR_INPUT, IdstyIMEShareSubText | IdstyIMEShareRGBCol);

      ....

      pIMEShare->FDeleteIMEShare();
    }
  }
  FreeLibrary(hImeShare);
}

Of cource, I have a patch for Firefox 1.1. But coming soon...

May 3, 2005

We have to consider Stack Alignment on Windows x64

When you enable optimize using as O1 / O2 option, you have to consider stack alignment. Because Microsoft C/C++ compliler uses movdqa opcode to stack to backup some registers such as SSE (XMM) registers.

So, when you use assember with x64 mode, you have to keep stack alignment to 16 bytes. If you don't do it, Windows will throws Access Violation by movdqa opcode.

Also, CL.EXE sometimes generate SSE code for structure copy. Because, about 16bytes copy, "movdqa" opcode seems to be faster than other opcode. "movdqa" is new opcode from SSE2. Intel says, "movdqa" is fastest in copying 16 bytes data.

Here is an article about movdqa opcode. http://akiba.ascii24.com/akiba/column/latestparts/2004/03/01/print/648472.html (This is Japanese page). According to it, when we use Prescott 3.2GH, average speed of this opcode is 45GB per seconds.

December 31, 2004

new CL.EXE bug...orz

When I use /O2 option for CL.EXE, it seems to generate bad code...

0:000>u nspr4!dosprintf
nspr4!dosprintf
00000000`30009650 488bc4           mov     rax,rsp
00000000`30009653 4881ec08020000   sub     rsp,0x208
00000000`3000965a 488958f8         mov     [rax-0x8],rbx
00000000`3000965e 488968f0         mov     [rax-0x10],rbp
00000000`30009662 4c8960d8         mov     [rax-0x28],r12
00000000`30009666 4d8be0           mov     r12,r8
00000000`30009669 488bda           mov     rbx,rdx
00000000`3000966c 488be9           mov     rbp,rcx
00000000`3000966f 4c8d4c2470       lea     r9,[rsp+0x70]
00000000`30009674 4c8d442450       lea     r8,[rsp+0x50]
00000000`30009679 498bd4           mov rdx,r12
00000000`3000967c 488bcb           mov  rcx,rbx
00000000`3000967f 4c8970c8         mov     [rax-0x38],r14
00000000`30009683 48c744244800000000 mov   qword ptr [rsp+0x48],0x0
00000000`3000968c e8bffaffff      call    nspr4!BuildArgArray (0000000030009150)
00000000`30009691 8b542450         mov edx,[rsp+0x50]
00000000`30009695 85d2             test    edx,edx
00000000`30009697 4c8bf0           mov     r14,rax
00000000`3000969a 7907            jns nspr4!dosprintf+0x53 (00000000300096a3)
00000000`3000969c 8bc2             mov     eax,edx
00000000`3000969e e94c060000     jmp nspr4!dosprintf+0x69f (0000000030009cef)
00000000`300096a3 0fb603           movzx   eax,byte ptr [rbx]
00000000`300096a6 4889b424f0010000 mov     [rsp+0x1f0],rsi
00000000`300096ae 4889bc24e8010000 mov     [rsp+0x1e8],rdi
00000000`300096b6 84c0             test    al,al
00000000`300096b8 4c89ac24d8010000 mov     [rsp+0x1d8],r13
00000000`300096c0 4c89bc24c8010000 mov     [rsp+0x1c8],r15
00000000`300096c8 660f7fb424b0010000 movdqa oword ptr [rsp+0x1b0],xmm6
00000000`300096d1 0f84c1050000    je nspr4!dosprintf+0x648 (0000000030009c98)
00000000`300096d7 4c8b7c2448       mov r15,[rsp+0x48]
00000000`300096dc 66666690         nop
00000000`300096e0 48ffc3           inc rbx

If xmm8 is uninitalized, Athlon64 throws error such as AV.

When I use /Od, ...

0:000> u nspr4!dosprintf
nspr4!dosprintf
00000000`3000a4f0 4c89442418 mov     [rsp+0x18],r8
00000000`3000a4f5 4889542410       mov [rsp+0x10],rdx
00000000`3000a4fa 48894c2408       mov     [rsp+0x8],rcx
00000000`3000a4ff 4881ec58020000 sub rsp,0x258
00000000`3000a506 48c784248000000000000000 mov qword ptr [rsp+0x80],0x0
00000000`3000a512 48c78424f801000000000000 mov qword ptr [rsp+0x1f8],0x0
00000000`3000a51e 4c8d8c24a0000000 lea r9,[rsp+0xa0]
00000000`3000a526 4c8d8424e0010000 lea r8,[rsp+0x1e0]
00000000`3000a52e 488b942470020000 mov rdx,[rsp+0x270]
00000000`3000a536 488b8c2468020000 mov rcx,[rsp+0x268]
00000000`3000a53e e84d1e0000      call nspr4!BuildArgArray (000000003000c390)
00000000`3000a543 4889842480000000 mov [rsp+0x80],rax
00000000`3000a54b 83bc24e001000000 cmp     dword ptr [rsp+0x1e0],0x0
00000000`3000a553 7d0c            jge nspr4!dosprintf+0x71 (000000003000a561)
00000000`3000a555 8b8424e0010000 mov eax,[rsp+0x1e0]
00000000`3000a55c e95e0f0000     jmp nspr4!dosprintf+0xfcf (000000003000b4bf)
00000000`3000a561 488b842468020000 mov rax,[rsp+0x268]
00000000`3000a569 0fb600 movzx eax,byte ptr [rax]
00000000`3000a56c 888424f0010000 mov [rsp+0x1f0],al
00000000`3000a573 0fbe8424f0010000 movsx   eax,byte ptr [rsp+0x1f0]
00000000`3000a57b 488b8c2468020000 mov     rcx,[rsp+0x268]
00000000`3000a583 48ffc1 inc rcx
00000000`3000a586 48898c2468020000 mov [rsp+0x268],rcx
00000000`3000a58e 85c0             test eax,eax
00000000`3000a590 0f84c60e0000    je nspr4!dosprintf+0xf6c (000000003000b45c)

This is right code. This is a bug of CL.EXE...

December 9, 2004

MIDL Compiler Version 6.00.0365

This version into SDK build 1218 has the following option, so source file generated by MIDL works fine.

Microsoft (R) 32b/64b MIDL Compiler Version 6.00.0365
Copyright (c) Microsoft Corporation 1991-2002. All rights reserved.
 :
 :
/env ia64          Target environment is Microsoft Windows 64-bit (NT) for IA64
/env x64           Target environment is Microsoft Windows for 64-Bit Extended Systems
Source is ...
/* this ALWAYS GENERATED file contains the proxy stub code */


/* File created by MIDL compiler version 6.00.0365 */
/* at Thu Dec 09 00:53:31 2004
*/
/* Compiler settings for ./ISimpleDOMDocument.idl:
    Oicf, W1, Zp8, env=Win64 (32b run)
    protocol : dce , ms_ext, c_ext, robust
    error checks: allocation ref bounds_check enum stub_data
    VC __declspec() decoration level:
         __declspec(uuid()), __declspec(selectany), __declspec(novtable)
         DECLSPEC_UUID(), MIDL_INTERFACE()
*/
//@@MIDL_FILE_HEADING( )

#if defined(_M_AMD64)

December 5, 2004

CL.EXE bug

Although I am explaining on this entry, this isn't fixed on CL.EXE of SDK build1218 yet...

November 12, 2004

CL.EXE for AMD64 (on SDK build 1218)

Today, I downloaded SDK build 1218 from MSDN subscription. When I try testing this compiler, I notice the following.
  • /GS is default (stack check)
  • Default install directory is changed to \Program File\Microsoft Platform SDK

November 6, 2004

SDK update

On MSDN subscription, new SDK is posted. I hope that compiler bug is fixed.

May 19, 2004

*this = aRect is generated as movaps xmm?,???

CL.EXE for AMD64 generated strength code...
(654.2a0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling. This exception may be expected and handled.
gklayout!nsStackLayout::Layout+0x83:
000007ff`fe51df8f 0f286c2440 movaps xmm5,oword ptr [rsp+0x40] ss:000007ff`fff88158=000027ba000033bd0000000000000000
0:000> u
gklayout!nsStackLayout::Layout+0x83 [c:\works\mozilla\mozilla\layout\xul\base\src\nsstacklayout.cpp @ 272]:
000007ff`fe51df8f 0f286c2440       movaps  xmm5,oword ptr [rsp+0x40]
000007ff`fe51df94 660f7f6c2430     movdqa  oword ptr [rsp+0x30],xmm5
000007ff`fe51df9a ff1500eb3d00 call qword ptr [gklayout!_imp_?DeflatensRectQEAAXAEBUnsMarginZ (000007fffe8fcaa0)]
000007ff`fe51dfa0 8b44243c         mov     eax,[rsp+0x3c]
000007ff`fe51dfa4 448b5c2438       mov     r11d,[rsp+0x38]
000007ff`fe51dfa9 488b4c2420       mov     rcx,[rsp+0x20]
000007ff`fe51dfae 453bdd           cmp     r11d,r13d
000007ff`fe51dfb1 44896c2458       mov  [rsp+0x58],r13d
Source code ... mozilla/layout/xul/base/src/nsStackLayout.cpp
NS_IMETHODIMP
nsStackLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
{
 :
 :
    while (child)
    {
        nsMargin margin;
        child->GetMargin(margin);
        nsRect childRect(clientRect);
mozilla/gfx/public/nsRect.h
struct NS_GFX nsRect {
    nscoord x, y;
    nscoord width, height;

    // Constructors
    nsRect() : x(0), y(0), width(0), height(0) {}
    nsRect(const nsRect& aRect) {*this = aRect;}
    nsRect(const nsPoint& aOrigin, const nsSize &aSize) {x = aOrigin.x; y = aOrigin.y;
This seems to be bug of compiler...

May 17, 2004

midl.exe doesn't support AMD64 platform

When I try to port mozilla/accecibility, I notice that current MIDL.EXE doesn't support AMD64 platform. Even if it launch with /win64, it generates proxy code for Itanimum only. So although I updated SDK to latest (from MSDN), it keeps the limitation... Is this fixed until RTM??
/* this ALWAYS GENERATED file contains the proxy stub code */


/* File created by MIDL compiler version 6.00.0364 */
/* at Mon May 17 14:44:59 2004
*/
/* Compiler settings for ./ISimpleDOMNode.idl:
    Oicf, W1, Zp8, env=Win64 (32b run)
    protocol : dce , ms_ext, c_ext, robust
    error checks: allocation ref bounds_check enum stub_data
    VC __declspec() decoration level:
        __declspec(uuid()), __declspec(selectany), __declspec(novtable)
        DECLSPEC_UUID(), MIDL_INTERFACE()
*/
//@@MIDL_FILE_HEADING( )

#if defined(_M_IA64)